Maxsus route dekoratorlari
Nest dekoratorlar deb ataladigan til xususiyati atrofida qurilgan. Dekoratorlar ko'plab keng qo'llaniladigan dasturlash tillarida yaxshi tanish tushuncha, ammo JavaScript olamida u
Nest dekoratorlar deb ataladigan til xususiyati atrofida qurilgan. Dekoratorlar ko'plab keng qo'llaniladigan dasturlash tillarida yaxshi tanish tushuncha, ammo JavaScript olamida ular hali nisbatan yangi. Dekoratorlar qanday ishlashini yaxshiroq tushunish uchun ushbu maqolani o'qishni tavsiya qilamiz. Quyida sodda ta'rif keltirilgan:
ES2016 dekoratori funksiya qaytaradigan va target, name hamda property descriptorni argument sifatida qabul qiladigan ifodadir.
Uni dekoratorni @ belgisi bilan oldindan qo'yib va dekoratsiya qilmoqchi bo'lgan narsaning eng yuqori qismiga joylashtirib qo'llaysiz.
Dekoratorlar sinf, metod yoki xossa uchun aniqlanishi mumkin.
Param dekoratorlar
Nest HTTP route handlerlar bilan birga foydalanishingiz mumkin bo'lgan foydali param dekoratorlar to'plamini taqdim etadi. Quyida taqdim etilgan dekoratorlar va ular ifodalovchi oddiy Express (yoki Fastify) obyektlari ro'yxati keltirilgan.
@Request(), @Req() | req |
@Response(), @Res() | res |
@Next() | next |
@Session() | req.session |
@Param(param?: string) | req.params / req.params[param] |
@Body(param?: string) | req.body / req.body[param] |
@Query(param?: string) | req.query / req.query[param] |
@Headers(param?: string) | req.headers / req.headers[param] |
@Ip() | req.ip |
@HostParam() | req.hosts |
Bundan tashqari, siz o'zingizning maxsus dekoratorlaringizni ham yaratishingiz mumkin. Bu nima uchun foydali?
node.js dunyosida request obyektiga xossalarni biriktirish odatiy amaliyotdir. So'ng har bir route handlerda ularni quyidagi kabi kod bilan qo'lda ajratasiz:
1const user = req.user;Kodingizni yanada o'qilishi oson va shaffof qilish uchun @User() dekoratorini yaratib, uni barcha controllerlaringiz bo'ylab qayta ishlatishingiz mumkin.
1import { createParamDecorator, ExecutionContext } from '@nestjs/common';
2
3export const User = createParamDecorator(
4 (data: unknown, ctx: ExecutionContext) => {
5 const request = ctx.switchToHttp().getRequest();
6 return request.user;
7 },
8);Keyin uni talablaringizga mos joylarda shunchaki ishlatasiz.
1@Get()
2async findOne(@User() user: UserEntity) {
3 console.log(user);
4}Ma'lumot uzatish
Agar dekoratoringiz xatti-harakati qandaydir shartlarga bog'liq bo'lsa, data parametridan foydalanib dekoratorning factory funksiyasiga argument uzatishingiz mumkin. Buning bir foydalanish holati - request obyektidan kalit bo'yicha xossalarni ajratib oladigan maxsus dekorator. Masalan, authentication layer so'rovlarni tekshiradi va request obyektiga user entity ni biriktiradi, deb tasavvur qilaylik. Autentifikatsiyadan o'tgan so'rov uchun user entity quyidagicha ko'rinishi mumkin:
1{
2 "id": 101,
3 "firstName": "Alan",
4 "lastName": "Turing",
5 "email": "alan@email.com",
6 "roles": ["admin"]
7}Keling, kalit sifatida xossa nomini qabul qilib, mavjud bo'lsa tegishli qiymatni (mavjud bo'lmasa yoki user obyekti yaratilmagan bo'lsa, undefined) qaytaradigan dekoratorni aniqlaylik.
1import { createParamDecorator, ExecutionContext } from '@nestjs/common';
2
3export const User = createParamDecorator(
4 (data: string, ctx: ExecutionContext) => {
5 const request = ctx.switchToHttp().getRequest();
6 const user = request.user;
7
8 return data ? user?.[data] : user;
9 },
10);So'ng controllerda @User() dekoratori orqali muayyan xossaga qanday kirishingiz mumkin:
1@Get()
2async findOne(@User('firstName') firstName: string) {
3 console.log(`Hello ${firstName}`);
4}Siz shu dekoratordan turli kalitlar bilan foydalanib, turli xossalarga kirishingiz mumkin. Agar user obyekti chuqur yoki murakkab bo'lsa, bu request handler implementatsiyalarini yanada oson va o'qilishi qulay qiladi.
TypeScript foydalanuvchilari uchun eslatma: createParamDecorator<T>() generic hisoblanadi. Bu sizga tip xavfsizligini aniq belgilash imkonini beradi, masalan createParamDecorator<string>((data, ctx) => ...). Muqobil ravishda, factory funksiyasida parametr tipini ko'rsatishingiz mumkin, masalan createParamDecorator((data: string, ctx) => ...). Agar ikkalasini ham qoldirsangiz, data uchun tip any bo'ladi.
Pipe'lar bilan ishlash
Nest maxsus param dekoratorlarini o'rnatilganlari (@Body(), @Param() va @Query()) bilan bir xil tarzda ko'rib chiqadi. Bu pipe'lar maxsus anotatsiya qilingan parametrlarga ham qo'llanadi (bizning misollarda user argumenti). Bundan tashqari, pipe'ni to'g'ridan-to'g'ri maxsus dekoratorga qo'llashingiz mumkin:
1@Get()
2async findOne(
3 @User(new ValidationPipe({ validateCustomDecorators: true }))
4 user: UserEntity,
5) {
6 console.log(user);
7}validateCustomDecorators opsiyasi true ga o'rnatilishi kerak. ValidationPipe odatda maxsus dekoratorlar bilan belgilangan argumentlarni validatsiya qilmaydi.
Dekoratorlar kompozitsiyasi
Nest bir nechta dekoratorlarni kompozitsiya qilish uchun yordamchi metod taqdim etadi. Masalan, autentifikatsiyaga oid barcha dekoratorlarni bitta dekoratorga birlashtirmoqchi bo'lsangiz. Buni quyidagi konstruktsiya bilan qilish mumkin:
1import { applyDecorators } from '@nestjs/common';
2
3export function Auth(...roles: Role[]) {
4 return applyDecorators(
5 SetMetadata('roles', roles),
6 UseGuards(AuthGuard, RolesGuard),
7 ApiBearerAuth(),
8 ApiUnauthorizedResponse({ description: 'Unauthorized' }),
9 );
10}Keyin ushbu maxsus @Auth() dekoratorini quyidagicha ishlatishingiz mumkin:
1@Get('users')
2@Auth('admin')
3findAllUsers() {}Bu bitta deklaratsiya bilan to'rtta dekoratorning barchasi qo'llanishi bilan yakunlanadi.
@nestjs/swagger paketidagi @ApiHideProperty() dekoratori kompozitsiya qilinmaydi va applyDecorators funksiyasi bilan to'g'ri ishlamaydi.