# @eggjs/controller-plugin

> controller decorator plugin for egg

Latest version **4.1.0** (published 2026-10-07) · 0 weekly downloads

## Install

```sh
npm install @eggjs/controller-plugin
pnpm add @eggjs/controller-plugin
yarn add @eggjs/controller-plugin
bun add @eggjs/controller-plugin
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 4.1.0 |
| Published | 2026-10-07 |
| First published | 2025-10-23 |
| Weekly downloads | 0 |
| TypeScript types | bundled |
| Module format | ESM |
| Node | >=22.18.0 |
| Dependencies | 19 |
| Unpacked size | 70 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| Maintainers | gxkl, eggjs-admin, fengmk2, atian25, hyj1991, killagu, coolme200, akitasummer, elrrrrrrr, niania |
| Keywords | egg, module, plugin, tegg, typescript |

## Links

- npm: https://www.npmjs.com/package/@eggjs/controller-plugin
- Repository: https://github.com/eggjs/egg
- Homepage: https://github.com/eggjs/egg/tree/next/tegg/plugin/controller
- Issues: https://github.com/eggjs/egg/issues
- npm.io page: https://npm.io/package/@eggjs/controller-plugin

## Dependencies (19)

- [globby](https://npm.io/package/globby.md) ^11.0.2
- [raw-body](https://npm.io/package/raw-body.md) ^2.5.2
- [sdk-base](https://npm.io/package/sdk-base.md) ^5.0.1
- [await-event](https://npm.io/package/await-event.md) 2
- [koa-compose](https://npm.io/package/koa-compose.md) ^4.1.0
- [content-type](https://npm.io/package/content-type.md) ^1.0.5
- [path-to-regexp](https://npm.io/package/path-to-regexp.md) ^1.9.0
- [@eggjs/metadata](https://npm.io/package/@eggjs/metadata.md) 4.1.0
- [@eggjs/lifecycle](https://npm.io/package/@eggjs/lifecycle.md) 4.1.0
- [@eggjs/tegg-types](https://npm.io/package/@eggjs/tegg-types.md) 4.1.0
- [@eggjs/tegg-loader](https://npm.io/package/@eggjs/tegg-loader.md) 4.1.0
- [@eggjs/tegg-runtime](https://npm.io/package/@eggjs/tegg-runtime.md) 4.1.0
- [@eggjs/agent-runtime](https://npm.io/package/@eggjs/agent-runtime.md) 4.1.0
- [@eggjs/module-common](https://npm.io/package/@eggjs/module-common.md) 4.1.0
- [@eggjs/core-decorator](https://npm.io/package/@eggjs/core-decorator.md) 4.1.0
- [@eggjs/tegg-common-util](https://npm.io/package/@eggjs/tegg-common-util.md) 4.1.0
- [@eggjs/controller-runtime](https://npm.io/package/@eggjs/controller-runtime.md) 4.1.0
- [@modelcontextprotocol/sdk](https://npm.io/package/@modelcontextprotocol/sdk.md) ^1.23.0
- [@eggjs/controller-decorator](https://npm.io/package/@eggjs/controller-decorator.md) 4.1.0

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 4.1.0 (latest) — 2026-10-07
- 4.0.2-rc.1 (rc) — 2026-10-06
- 4.0.2-beta.27 (beta) — 2026-09-20
- 4.0.2 — 2026-10-06
- 4.0.2-rc.0 — 2026-09-23
- 4.0.2-beta.26 — 2026-08-07
- 4.0.2-beta.25 — 2026-07-13
- 4.0.2-beta.24 — 2026-07-12
- 4.0.2-beta.23 — 2026-07-11
- 4.0.2-beta.22 — 2026-07-11
- 4.0.2-beta.20 — 2026-07-09
- 4.0.2-beta.19 — 2026-06-29
- 4.0.2-beta.17 — 2026-06-28
- 4.0.2-beta.16 — 2026-06-26
- 4.0.2-beta.15 — 2026-06-26
- … 24 more at https://npm.io/package/@eggjs/controller-plugin/versions

## README

# @eggjs/controller-plugin

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

[npm-image]: https://img.shields.io/npm/v/@eggjs/controller-plugin.svg?style=flat-square
[npm-url]: https://npmjs.org/package/@eggjs/controller-plugin
[snyk-image]: https://snyk.io/test/npm/@eggjs/controller-plugin/badge.svg?style=flat-square
[snyk-url]: https://snyk.io/test/npm/@eggjs/controller-plugin
[download-image]: https://img.shields.io/npm/dm/@eggjs/controller-plugin.svg?style=flat-square
[download-url]: https://npmjs.org/package/@eggjs/controller-plugin

使用注解的方式来开发 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() {}
}
```

---
_Source: https://npm.io/package/@eggjs/controller-plugin · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
