# @eggjs/controller-plugin 中文文档

规范地址：https://npmcn.com/package/%40eggjs/controller-plugin/

版本：4\.1\.0
npm 元数据更新时间：2026-10-07T08:27:03.054Z
中文译文更新时间：2026-11-13T12:46:58.111Z
软件包许可：未声明

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40eggjs/controller-plugin
原文对照：https://npmcn.com/package/%40eggjs/controller-plugin/?lang=original
项目主页：https://github.com/eggjs/egg/tree/next/tegg/plugin/controller
源码仓库：https://github.com/eggjs/egg

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：71.6 kB，40 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.18\.0
- 运行依赖：19 个
- peer 依赖：egg 4\.2\.0，@eggjs/tegg-plugin 4\.1\.0
- 首次发布：2025-10-23T16:50:53.920Z
- 最新版本发布：2026-10-07T08:27:02.642Z
- 近 30 天下载量：3925（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：39（近 12 个月 33 个）

## 中文简介

鸡蛋控制器装饰插件

## 安装

```sh
npm install @eggjs/controller-plugin
```

也可以使用：`pnpm add @eggjs/controller-plugin`、`yarn add @eggjs/controller-plugin`、`bun add @eggjs/controller-plugin`

## README

# @eggjs/controller-plugin

[![NPM version](https://img.shields.io/npm/v/@eggjs/controller-plugin.svg?style=flat-square)](https://npmjs.org/package/@eggjs/controller-plugin) [![Known Vulnerabilities](https://snyk.io/test/npm/@eggjs/controller-plugin/badge.svg?style=flat-square)](https://snyk.io/test/npm/@eggjs/controller-plugin) [![npm download](https://img.shields.io/npm/dm/@eggjs/controller-plugin.svg?style=flat-square)](https://npmjs.org/package/@eggjs/controller-plugin) [![Node.js Version](https://img.shields.io/node/v/@eggjs/controller-plugin.svg?style=flat)](https://nodejs.org/en/download/)

使用注解的方式来开发 egg 中的 Controller

## Install

```shell
# tegg 注解
npm i --save @eggjs/tegg@beta
# tegg 插件
npm i --save @eggjs/tegg-plugin@beta
# tegg controller 插件
npm i --save @eggjs/controller-plugin@beta
```

## Prepare

```json
// tsconfig.json
{
  "extends": "@eggjs/tsconfig"
}
```

## Config

```js
// config/plugin.js
exports.tegg = {
  package: '@eggjs/tegg-plugin',
  enable: true,
};

exports.teggController = {
  package: '@eggjs/controller-plugin',
  enable: true,
};
```

## Usage

### Middleware

Middleware 支持多个入参，依次传入要生效的中间件 中间件注解，可以添加在类/方法上。添加在类上时，对类上所有方法生效，添加在方法上时，只对当前方法生效。

```ts
// app/middleware/global_log.ts
import type { Context } from 'egg';
import type { Next } from '@eggjs/controller-decorator';

export default async function globalLog(ctx: Context, next: Next) {
  ctx.logger.info('have a request');
  return next();
}

export default async function globalLog2(ctx: Context, next: Next) {
  ctx.logger.info('have a request2');
  return next();
}

// app/controller/FooController.ts
import { Middleware } from '@eggjs/tegg';
@Middleware(globalLog, globalLog2)
export class FooController {
  @Middleware(methodCount)
  async hello() {}
}
```

需要依赖注入的 controller 中间件继续使用 `@Advice` 和 `@Middleware`， 并继承 `AbstractControllerAdvice`。`next()` 返回时，controller 的返回值已经 写入 `ctx.body`，因此中间件可以读取或替换最终响应。 需要调用信息时，可以声明第三个 `AdviceContext` 参数；其中包含实际的 controller 对象、方法名和绑定后的参数。

```ts
import { AbstractControllerAdvice, Middleware, type EggContext } from '@eggjs/tegg';
import { Advice } from '@eggjs/tegg/aop';

@Advice()
export class WrapResponse extends AbstractControllerAdvice<EggContext> {
  async middleware(ctx: EggContext, next: () => Promise<void>): Promise<void> {
    await next();
    ctx.body = { data: ctx.body };
  }
}

@Middleware(WrapResponse)
export class FooController {}
```

通过 `@Middleware` 声明的普通 Advice 只执行 `around()`；没有实现 `around()` 时会直接执行 下一个 middleware。`AbstractControllerAdvice.around()` 会把 context、`next` 和 `AdviceContext` 转发给已有的 `middleware()` 契约。显式 `@Pointcut` 的行为不变。

### Context

当需要 egg context 时，可以使用 `@Context` 注解来声明。

```ts
// app/controller/FooController.ts
import { Context, EggContext } from '@eggjs/tegg';

export class FooController {
  @Middleware(methodCount)
  async hello(@Context() ctx: EggContext) {}
}
```

### HTTP 注解

#### HTTPController/HTTPMethod

`@HTTPController` 注解用来声明当前类是一个 HTTP controller，可以配置路径前缀。 `@HTTPMethod` 注解用来声明当前方法是一个 HTTP method，只有带了这个注解，HTTP 方法才会被暴露出去，可以配置方法路径，

```ts
// app/controller/FooController.ts
import { Context, EggContext, HTTPController, HTTPMethod, HTTPMethodEnum } from '@eggjs/tegg';

@HTTPController({
  path: '/foo',
})
export class FooController {
  @HTTPMethod({
    method: HTTPMethodEnum.GET,
    path: '/hello',
  })
  async hello() {}
}
```

#### Param

HTTP 协议中有各种各样的传参方式，比如 query,path,body 等等。

##### HTTPBody

接收 body 参数

```ts
// app/controller/FooController.ts
import { Context, EggContext, HTTPController, HTTPMethod, HTTPMethodEnum, HTTPBody } from '@eggjs/tegg';

@HTTPController({
  path: '/foo',
})
export class FooController {
  @HTTPMethod({
    method: HTTPMethodEnum.GET,
    path: '/hello',
  })
  async hello(@HTTPBody() name: string) {
    return `hello, ${name}`;
  }
}
```

##### HTTPQuery/HTTPQueries

两者的区别在于参数是否为数组， HTTPQuery 只会取第一个参数，HTTPQueries 只提供数组形式。 HTTPQuery 的参数类型只能是 string, HTTPQueries 的参数类型只能是 string\[\]。

```ts
// app/controller/FooController.ts
import { Context, EggContext, HTTPController, HTTPMethod, HTTPMethodEnum, HTTPQuery, HTTPQueries } from '@eggjs/tegg';

@HTTPController({
  path: '/foo',
})
export class FooController {
  @HTTPMethod({
    method: HTTPMethodEnum.GET,
    path: '/hello',
  })
  async hello(
    // /foo/hello?name=bar
    // HTTPQuery: name=bar
    // HTTPQueries: name=[bar]
    @HTTPQuery() name: string,
    @HTTPQueries() names: string[],
  ) {
    return `hello, ${name}`;
  }
}
```

如果需要使用别名，比如说 query 中的 name 不能在 js 中声明时，如 foo\[bar\] 这类的。可以通过以下形式

```ts
@HTTPQuery({ name: 'foo[bar]' }) fooBar: string,
```

##### HTTPParam

接收 path 中的参数，类型只能为 string

```ts
// app/controller/FooController.ts
import { Context, EggContext, HTTPController, HTTPMethod, HTTPMethodEnum, HTTPBody } from '@eggjs/tegg';

@HTTPController({
  path: '/foo',
})
export class FooController {
  @HTTPMethod({
    method: HTTPMethodEnum.GET,
    path: '/:id',
  })
  async hello(@HTTPParam() id: string) {
    return `hello, ${name}`;
  }
}
```

如果需要使用别名，比如说 path 中使用正则声明 `/foo/(.*)`, 可以通过以下形式

```ts
// 具体 name 值可以查看 path-to-regexp
@HTTPParam({ name: '0' }) id: string
```

### Host

Host 注解，用于指定 HTTP 方法仅在 host 匹配时执行。 可以添加在类/方法上。添加在类上时，对类上所有方法生效，添加在方法上时，只对当前方法生效。方法上的注解可以覆盖类上的注解

```ts
// app/controller/FooController.ts
import { Host } from '@eggjs/tegg';
@Host('foo.eggjs.com')
export class FooController {
  // 仅能通过 foo.eggjs.com 访问
  async hello() {}

  // 仅能通过 bar.eggjs.com 访问
  @Host('bar.eggjs.com')
  async bar() {}
}
```

## 常见问题

### @eggjs/controller-plugin 是什么？

鸡蛋控制器装饰插件

### 如何安装 @eggjs/controller-plugin？

在项目目录运行 npm install @eggjs/controller-plugin，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：egg（4\.2\.0）、@eggjs/tegg-plugin（4\.1\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @eggjs/controller-plugin 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @eggjs/controller-plugin 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @eggjs/controller-plugin 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22\.18\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @eggjs/controller-plugin 可以商用吗？

@eggjs/controller-plugin 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @eggjs/controller-plugin 的下载量有多少？

根据 npm 官方下载统计，@eggjs/controller-plugin 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,925 次，日均约 131 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @eggjs/controller-plugin 还在维护吗？

最新版本 4\.1\.0 发布于 2026/10/07（1 个月前）；至今共发布 39 个版本，其中过去 12 个月发布了 33 个；首次发布于 2025/10/24。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

