Nestjs 項(xiàng)目中,這九個(gè)裝飾器是必不可少的!
作者:林三心不學(xué)挖掘機(jī)
Nestjs 項(xiàng)目中,這 9 個(gè)裝飾器分別為權(quán)限驗(yàn)證裝飾器 - @Roles(),請(qǐng)求日志裝飾器 - @LogRequest(),緩存裝飾器 - @Cache()等。
前言
大家好,我是林三心,用最通俗易懂的話講最難的知識(shí)點(diǎn)是我的座右銘,基礎(chǔ)是進(jìn)階的前提是我的初心~
一、權(quán)限驗(yàn)證裝飾器 - @Roles()
基于角色的訪問控制(RBAC),限制接口訪問權(quán)限
// src/decorators/roles.decorator.ts
import { SetMetadata } from'@nestjs/common';
// 定義角色枚舉
exportenum UserRole {
ADMIN = 'admin',
EDITOR = 'editor',
USER = 'user'
}
/**
* 角色權(quán)限裝飾器
* @param roles 允許訪問的角色數(shù)組
* 使用示例:@Roles([UserRole.ADMIN])
*/
exportconst Roles = (...roles: UserRole[]) => SetMetadata('roles', roles);
// 在守衛(wèi)中使用:
@Injectable()
exportclass RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.get<UserRole[]>(
'roles',
context.getHandler()
);
// ...驗(yàn)證邏輯
}
}
二、請(qǐng)求日志裝飾器 - @LogRequest()
自動(dòng)記錄完整的HTTP請(qǐng)求信息
// src/decorators/log-request.decorator.ts
import { createParamDecorator, ExecutionContext } from'@nestjs/common';
/**
* 記錄請(qǐng)求完整信息
* 使用示例:@LogRequest()
*/
exportconst LogRequest = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return {
url: request.url,
method: request.method,
headers: request.headers,
body: request.body,
timestamp: newDate().toISOString()
};
}
);
// 在控制器中使用:
@Get()
async findOne(@LogRequest() logData: any) {
// logData會(huì)包含完整的請(qǐng)求信息
}
三、緩存裝飾器 - @Cache()
聲明式接口響應(yīng)緩存,提升性能
// src/decorators/cache.decorator.ts
import { applyDecorators, UseInterceptors } from'@nestjs/common';
import { CacheInterceptor } from'@nestjs/cache-manager';
/**
* 自定義緩存裝飾器
* @param ttl 緩存時(shí)間(秒)
* 使用示例:@Cache(60)
*/
exportfunction Cache(ttl: number) {
return applyDecorators(
UseInterceptors(CacheInterceptor),
SetMetadata('cacheTTL', ttl)
);
}
// 在服務(wù)層配置:
@Injectable()
exportclass CustomCacheInterceptor extends CacheInterceptor {
protected trackBy(context: ExecutionContext): string | undefined {
const ttl = this.reflector.get<number>('cacheTTL', context.getHandler());
// ...自定義緩存邏輯
}
}
四、事務(wù)管理裝飾器 - @Transactional()
自動(dòng)管理數(shù)據(jù)庫事務(wù),保證數(shù)據(jù)一致性
// src/decorators/transaction.decorator.ts
import { Transaction } from'typeorm-transactional';
/**
* 數(shù)據(jù)庫事務(wù)裝飾器
* 使用示例:@Transactional()
*/
exportconst Transactional = () => (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) => {
const originalMethod = descriptor.value;
descriptor.value = asyncfunction (...args: any[]) {
return Transaction({ isolationLevel: 'READ COMMITTED' })(
originalMethod.bind(this)
.apply(this, args)
);
};
return descriptor;
};
五、參數(shù)驗(yàn)證裝飾器 - @ValidateId()
參數(shù)格式預(yù)校驗(yàn),防止非法輸入
// src/decorators/validate-param.decorator.ts
import {
createParamDecorator,
BadRequestException
} from'@nestjs/common';
/**
* ID參數(shù)格式驗(yàn)證
* 使用示例:@ValidateId() id: string
*/
exportconst ValidateId = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
const id = request.params.id;
if (!/^[a-f\d]{24}$/i.test(id)) {
thrownew BadRequestException('Invalid ID format');
}
return id;
}
);
六、響應(yīng)格式裝飾器 - @StandardResponse()
統(tǒng)一API響應(yīng)格式規(guī)范
// src/decorators/response-format.decorator.ts
import {
applyDecorators,
Type,
HttpCode,
Header
} from'@nestjs/common';
import { ApiResponse } from'@nestjs/swagger';
/**
* 統(tǒng)一響應(yīng)格式
* @param status HTTP狀態(tài)碼
* @param type 響應(yīng)數(shù)據(jù)類型
* 使用示例:@StandardResponse(200, UserDto)
*/
exportfunction StandardResponse<T>(status: number, type?: Type<T>) {
return applyDecorators(
HttpCode(status),
Header('Content-Type', 'application/json'),
ApiResponse({
status,
type,
description: 'Standard API response'
})
);
}
七、性能監(jiān)控裝飾器 - @Benchmark()
方法執(zhí)行耗時(shí)監(jiān)控與日志記錄
// src/decorators/benchmark.decorator.ts
import { Logger } from'@nestjs/common';
const logger = new Logger('Benchmark');
/**
* 方法執(zhí)行時(shí)間監(jiān)控
* 使用示例:@Benchmark()
*/
exportfunction Benchmark() {
returnfunction (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const originalMethod = descriptor.value;
descriptor.value = asyncfunction (...args: any[]) {
const start = Date.now();
try {
returnawait originalMethod.apply(this, args);
} finally {
const duration = Date.now() - start;
logger.log(`${propertyKey} executed in ${duration}ms`);
}
};
return descriptor;
};
}
八、多語言支持裝飾器 - @Translate()
便捷獲取國際化翻譯內(nèi)容
// src/decorators/i18n.decorator.ts
import { createParamDecorator } from'@nestjs/common';
import { I18nService } from'nestjs-i18n';
/**
* 獲取當(dāng)前語言文本
* 使用示例:@Translate() t: I18nService['translate']
*/
exportconst Translate = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const i18n = ctx.switchToHttp().getRequest().i18nService as I18nService;
return(key: string, options?: any) => i18n.translate(key, options);
}
);
九、版本控制裝飾器 - @ApiVersion()
API多版本共存管理
// src/decorators/version.decorator.ts
import { Controller, SetMetadata, applyDecorators } from'@nestjs/common';
import { Version } from'@nestjs/common';
/**
* API版本控制裝飾器
* @param versions 支持的版本數(shù)組
* 使用示例:@ApiVersion(['1', '2'])
*/
exportfunction ApiVersion(versions: string[]) {
return applyDecorators(
SetMetadata('apiVersions', versions),
Version(versions)
);
}
// 在控制器中使用:
@ApiVersion(['1', '2'])
@Controller('users')
exportclass UsersController {}
責(zé)任編輯:武曉燕
來源:
前端之神