Як створити та використовувати власні декоратори в NestJS?
Користувацькі декоратори в NestJS
NestJS широко використовує декоратори TypeScript для розробки, основаної на метаданих. Ви можете створювати власні декоратори, щоб зменшити обсяг повторюваного коду та додати повторно використовувану поведінку.
Типи користувацьких декораторів
1. Декоратор параметра
Витягування даних з запиту:
typescript
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const CurrentUser = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
const user = request.user;
return data ? user?.[data] : user;
},
);Використання:
typescript
@Controller('profile')
export class ProfileController {
@Get()
getProfile(@CurrentUser() user: User) {
return user;
}
@Get('email')
getEmail(@CurrentUser('email') email: string) {
return { email };
}
}2. Декоратор метаданих з SetMetadata
typescript
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
export const Public = () => SetMetadata('isPublic', true);Використання з охоронцями:
typescript
@Controller('admin')
export class AdminController {
@Get('dashboard')
@Roles('admin', 'superadmin')
getDashboard() {
return { message: 'Admin dashboard' };
}
@Get('health')
@Public()
healthCheck() {
return { status: 'ok' };
}
}3. Складений декоратор
Об'єднання кількох декораторів в один:
typescript
import { applyDecorators, UseGuards, SetMetadata } from '@nestjs/common';
import { ApiBearerAuth, ApiUnauthorizedResponse } from '@nestjs/swagger';
export function Auth(...roles: string[]) {
return applyDecorators(
SetMetadata('roles', roles),
UseGuards(JwtAuthGuard, RolesGuard),
ApiBearerAuth(),
ApiUnauthorizedResponse({ description: 'Unauthorized' }),
);
}Використання — чисто і без повторень:
typescript
@Controller('users')
export class UsersController {
@Get()
@Auth('admin')
findAll() {
return this.usersService.findAll();
}
}4. Декоратор класу
typescript
import { Controller, UseInterceptors } from '@nestjs/common';
export function ApiController(prefix: string) {
return applyDecorators(
Controller(`api/v1/${prefix}`),
UseInterceptors(LoggingInterceptor),
UseInterceptors(TransformInterceptor),
);
}typescript
@ApiController('users')
export class UsersController {
// Усі маршрути з префіксом /api/v1/users
// Застосовано LoggingInterceptor і TransformInterceptor
}5. Декоратор властивості (для валідації)
typescript
import { registerDecorator, ValidationOptions } from 'class-validator';
export function IsStrongPassword(validationOptions?: ValidationOptions) {
return function (object: object, propertyName: string) {
registerDecorator({
name: 'isStrongPassword',
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value: string) {
return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$/.test(value);
},
defaultMessage() {
return 'Пароль повинен містити великі, малі літери, цифри та спеціальні символи';
},
},
});
};
}Резюме
| Тип декоратора | Сценарій використання | API |
|---|---|---|
| Параметр | Витягування даних з запиту | createParamDecorator() |
| Метадані | Встановлення метаданих для охоронців/інтерсепторів | SetMetadata() |
| Складений | Об'єднання кількох декораторів | applyDecorators() |
| Клас | Застосування до всього контролера/класу | applyDecorators() |
| Властивість | Користувацькі правила валідації | registerDecorator() |
Найкраща практика: Користувацькі декоратори є потужними для зменшення обсягу повторюваного коду. Створюйте декоратори
@Auth(),@CurrentUser()та@Public()в кожному проекті NestJS — вони використовуються постійно.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.