
NestJS 里的装饰器很多,但新手最容易混的是:@Controller()、@Injectable() 这种“贴在类上”的,和 @Get()、@Post() 这种“贴在方法上”的,到底差在哪。最短的理解方式是:
- 类装饰器决定“这个类是什么”
- 方法装饰器决定“这个方法怎么被框架使用”

目录
先看三个层级
在 NestJS 里,常见装饰器大致可以分成:
- 类装饰器
- 方法装饰器
- 参数装饰器
这三个层级刚好对应“控制器是谁”“具体路由怎么进”“请求数据怎么取”。
类装饰器做什么
类装饰器贴在整个类上,用来告诉 Nest 这个类的角色。
import { Controller, Injectable } from "@nestjs/common"
@Controller("users")
export class UserController {}
@Injectable()
export class UserService {}
这类装饰器常见作用:
- 标记控制器
- 标记 provider / service
- 标记模块
Nest 官方控制器文档本身也是围绕 @Controller() 展开的:它负责把类和路由前缀关联起来。
方法装饰器做什么
方法装饰器贴在类的方法上,用来说明“这个方法对应什么行为”。
import { Controller, Get, Post } from "@nestjs/common"
@Controller("users")
export class UserController {
@Get()
findAll() {
return "all users"
}
@Post()
create() {
return "created"
}
}
最常见的是:
@Get()@Post()@Put()@Delete()@UseGuards()@UseInterceptors()
也就是说,类装饰器先告诉框架“这是哪栋楼”,方法装饰器再告诉框架“楼里的哪扇门处理什么请求”。
参数装饰器别混进方法装饰器里
很多人把 @Body()、@Param()、@Query() 也跟 @Get() 放一类,其实它们更接近“方法参数级别”的装饰器:
@Get(":id")
findOne(@Param("id") id: string) {
return id
}
它们解决的是“请求数据如何注入到这个参数”,而不是“这个方法绑定哪个路由”。
一次请求里它们分别在哪一层生效
可以把一条请求大致理解成:
请求进入
-> 通过 @Controller() 找到控制器前缀
-> 通过 @Get() / @Post() 找到具体方法
-> 通过 @Param() / @Body() 取数据
-> 调用 controller 方法
-> controller 调 service(通常由 @Injectable() 标记)
这就解释了为什么 @Injectable() 和 @Get() 根本不是同类东西。一个是在注册可注入类,一个是在声明路由处理器。
最容易混淆的几个点
@Controller() 和 @Get() 不是替代关系
它们通常一起出现,但解决的问题不同:
@Controller("users")提供类级路由前缀@Get()提供方法级 HTTP 映射
最终才得到完整路径。
@Injectable() 不会自动让方法变成路由
它只告诉 Nest 这个类可以参与依赖注入,常见于 service、repository、use case 层。
@UseGuards() 既能挂类,也能挂方法
这类装饰器容易让人困惑,因为它既可以类级应用,也可以方法级覆盖。判断方式很简单:看你是想整类共享,还是只限某个接口。
记忆法
- 类装饰器:这是什么角色
- 方法装饰器:这个方法处理什么请求或行为
- 参数装饰器:这个参数从哪里来
结论
@Controller()、@Injectable()这类是类装饰器,作用在整个类。@Get()、@Post()这类是方法装饰器,作用在具体方法。@Body()、@Param()这类是参数装饰器,负责把请求数据注入参数。
如果你接下来在写 DTO 校验、管道或响应拦截,最好把它们按“请求链路位置”继续拆开理解,而不是统称“装饰器语法”。
参考资料
继续阅读
- 如果你在 NestJS 里处理定时任务,可以看 Cron 是什么:从 0 到精通这门时间语言。
- 如果你正在整理后端项目配置,可以读 前端项目配置文件指南。
- 如果你想补 Node / 后端相关内容,可以继续看 反向代理是什么:Nginx 配置与排障指南。
继续阅读
Strapi 5 populate 完整指南:关联、媒体与嵌套查询
解释 Strapi 5 REST API 为什么默认不返回关联数据,并通过 populate=*、字段选择、嵌套 populate 和 qs 构造器展示可维护的查询方式与性能边界。
12 分钟Strapi 5 入门:安装、内容建模与 API 权限
从创建 Strapi 5 项目开始,说明 Collection Type、Single Type、Component 和 Dynamic Zone 的选择,并完成发布、权限配置与 REST API 验证。
8 分钟LocalSend 跨平台传文件指南:不用数据线和网盘
LocalSend 是免费的局域网文件传输工具,适合安卓、Windows、iPhone 与 Mac 混用的人。本文从安装、第一次传输到搜不到设备的排查,带你不用网盘完成跨平台互传。
订阅 FreeMac
每周精选:免费 Mac 软件评测、可信来源更新、替代方案和少折腾指南。