@Controller() 是 NestJS 中最核心的装饰器之一,用于定义一个类为控制器(Controller)。
在 MVC(模型 - 视图 - 控制器)或更现代的架构模式中,控制器负责处理传入的 HTTP 请求 ,调用业务逻辑(Service),并返回响应给客户端。它是应用程序的"入口大门"。
1. 基本用法
typescript
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
// 1. 使用 @Controller() 装饰器标记类
@Controller('cats') // 参数 'cats' 定义了路由前缀
export class CatsController {
// 2. 定义处理 GET 请求的方法
// 完整路径将是: GET /cats
@Get()
findAll(): string {
return 'This action returns all cats';
}
// 3. 定义处理 POST 请求的方法
// 完整路径将是: POST /cats
@Post()
create(@Body() createCatDto: any): string {
return 'This action adds a new cat';
}
// 4. 定义带参数的路由
// 完整路径将是: GET /cats/123
@Get(':id')
findOne(@Param('id') id: string): string {
return `This action returns a #${id} cat`;
}
}
2. @Controller() 的核心功能
A. 定义路由前缀 (Route Prefix)
@Controller() 可以接收一个字符串参数,该参数会成为该类中所有路由方法的公共前缀。
@Controller('users')+@Get('profile')-> 访问路径:/users/profile@Controller('api/v1/products')-> 适合做 API 版本控制。
B. 不传参数 (根路径)
如果不传参数 @Controller(),则该控制器处理的是根路径 / 下的请求。
@Controller()+@Get('home')-> 访问路径:/home
C. 依赖注入 (Dependency Injection)
控制器也是 NestJS 依赖注入系统的一部分。你可以像在 Service 中一样,在控制器的构造函数中注入 Service、Repository 或其他 Provider。
typescript
@Controller('cats')
export class CatsController {
// 注入 CatsService
constructor(private readonly catsService: CatsService) {}
@Post()
create(@Body() createCatDto: CreateCatDto) {
// 调用 Service 层的业务逻辑
return this.catsService.create(createCatDto);
}
}
3. 常用搭配的请求方法装饰器
在 @Controller 类内部,你需要使用方法装饰器来指定具体的 HTTP 动词和路径:
| 装饰器 | HTTP 方法 | 示例路径 (假设前缀为 'items') |
|---|---|---|
@Get() |
GET | /items (获取列表) |
@Post() |
POST | /items (创建资源) |
@Put() |
PUT | /items/:id (全量更新) |
@Patch() |
PATCH | /items/:id (部分更新) |
@Delete() |
DELETE | /items/:id (删除资源) |
@All() |
ALL | 匹配所有 HTTP 方法 |
你也可以传递具体路径:@Get('popular') -> /items/popular。
4. 进阶用法
A. 主机名限制 (Host)
你可以限制控制器只在特定的主机名下生效(适用于多租户或微服务)。
typescript
@Controller({ path: 'cats', host: 'api.example.com' })
export class CatsController {
@Get()
findAll() {
return 'This works only on api.example.com/cats';
}
}
B. 版本控制 (Versioning)
配合 NestJS 的版本控制功能,可以为不同的 API 版本定义不同的控制器。
typescript
@Controller({ path: 'cats', version: '2' })
export class CatsControllerV2 {
@Get()
findAll() {
return 'Returns data using v2 logic';
}
}
(需要在主应用中启用版本控制)
5. 最佳实践 (Best Practices)
-
职责单一:控制器应该非常"薄"。它只负责:
- 接收请求。
- 解析参数(通过
@Body,@Param,@Query)。 - 调用 Service。
- 返回结果。
- 不要 在控制器里写复杂的业务逻辑(如数据库查询、复杂计算),这些应该放在 Service 层。
-
使用 DTO (Data Transfer Objects) : 不要直接使用
any或object接收@Body()。应该定义专门的类(DTO)来验证和类型化输入数据,通常配合class-validator和ValidationPipe使用。typescript// 推荐做法 @Post() create(@Body() createCatDto: CreateCatDto) { ... } -
正确的状态码 : NestJS 默认 POST/PUT 返回 201 或 200。如果需要自定义,可以使用
@HttpCode()装饰器。typescript@Post() @HttpCode(201) // 明确指定创建成功返回 201 create() { ... }
总结
@Controller() 是 NestJS 应用的路由指挥中心。它将 HTTP 请求映射到具体的类方法上,并通过依赖注入连接业务逻辑层,是构建 RESTful API 的基石。