SetMetadata
是 NestJS 中一个非常重要且强大的装饰器,它属于元数据编程 的核心部分。
简单来说,它的主要功能是:在某个目标上(比如 Controller 类或 Handler 方法)"贴标签"或"附加自定义信息" 。
这些"标签"或"信息"本身不会做任何事,但可以被其他部分的代码(如 Guard、Interceptor、Filter)读取,并根据这些信息来执行不同的逻辑。
🎯 核心功能:创建自定义的"标记"
想象一下,你有一个安检系统(Guard),需要检查哪些地方是"VIP区域",只允许"VIP用户"进入。
- 问题:你如何告诉安检系统,哪个路由是"VIP区域"?
- 解决方案 :用
SetMetadata
在那个路由的处理函数上贴一个isVip: true
的标签。
SetMetadata
就是用来创建这个标签的工具。
🛠️ 如何使用 SetMetadata
SetMetadata
通常不直接使用,而是封装在一个自定义装饰器里,这样更清晰、更易于复用。
第 1 步:定义一个元数据的 Key
首先,定义一个常量作为你的"标签"名称,避免写错字符串。
arduino
// src/decorators/public.decorator.ts (或者 constants.ts)
export const IS_PUBLIC_KEY = 'isPublic';
第 2 步:创建自定义装饰器
然后,创建一个自定义装饰器,内部调用 SetMetadata
。
javascript
// src/decorators/public.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const IS_PUBLIC_KEY = 'isPublic';
/**
* 一个标记路由为公开的装饰器,跳过认证
*/
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
现在,你就拥有了一个 @Public()
装饰器。它做的事情就是:在它所装饰的目标上,设置一个名为 isPublic
的元数据,值为 true
。
第 3 步:使用自定义装饰器
现在你可以在任何 Controller 或 Handler 方法上使用这个装饰器了。
less
// src/auth/auth.controller.ts
import { Controller, Get } from '@nestjs/common';
import { Public } from '../decorators/public.decorator';
@Controller('auth')
export class AuthController {
@Public() // <-- 使用我们的自定义装饰器
@Get('login')
login() {
// 这个登录接口不需要认证,是公开的
return { message: 'This is a public login route' };
}
@Get('profile')
getProfile() {
// 这个接口需要认证
return { message: 'This is a protected route' };
}
}