NestJS — Node.js للمؤسسات

توثيق OpenAPI / Swagger

16 دقيقة الدرس 32 من 48

توثيق OpenAPI / Swagger

الواجهات البرمجية الجيدة ليست وظيفية فحسب — بل هي قابلة للاكتشاف. يمنح OpenAPI (المواصفة) وواجهة Swagger UI (متصفّح التوثيق التفاعلي) كلّ مستهلك عقدًا حيًّا وموصوفًا ذاتيًّا لنقاط النهاية. يقدّم NestJS دعمًا متكاملًا عبر @nestjs/swagger، الذي يقرأ مزخرفات TypeScript الخاصة بك ويولّد المواصفة تلقائيًّا.

التثبيت والإعداد

npm install @nestjs/swagger

شغّل Swagger في main.ts باستخدام SwaggerModule وDocumentBuilder:

import { NestFactory } from '@nestjs/core'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); const config = new DocumentBuilder() .setTitle('Tasks API') .setDescription('Manage user tasks') .setVersion('1.0') .addBearerAuth() // يُضيف زرّ التفويض لـ JWT .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('api-docs', app, document); // الواجهة على /api-docs await app.listen(3000); } bootstrap();
يُولَّد مرّة واحدة ويُخدَم للأبد. تفحص SwaggerModule.createDocument() كلّ متحكّم وكائن DTO في رسم بيانات تطبيقك وتنتج مستندًا JSON يتوافق مع مواصفة OpenAPI 3.0. يتوفّر JSON الخام على /api-docs-json لدمجه مع الأدوات الخارجية.

@ApiTags — تجميع المتحكّمات

ضع علامةً على متحكّم ليُجمَّع ضمن قسم مُسمَّى في الواجهة:

import { Controller, Get } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; @ApiTags('tasks') @Controller('tasks') export class TasksController { @Get() findAll() { /* ... */ } }

توثيق كائنات DTO باستخدام @ApiProperty

تُزيّن @ApiProperty كلّ حقل في كائن DTO، مانحةً Swagger النوع والوصف وقيمة المثال وقيود التحقّق الخاصة بمخطّط جسم الطلب:

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsString, IsNotEmpty, IsOptional, IsEnum } from 'class-validator'; export enum TaskStatus { OPEN = 'OPEN', IN_PROGRESS = 'IN_PROGRESS', DONE = 'DONE', } export class CreateTaskDto { @ApiProperty({ description: 'Short task title', example: 'Write unit tests' }) @IsString() @IsNotEmpty() title: string; @ApiPropertyOptional({ description: 'Longer description', example: 'Cover all service methods with Jest', }) @IsOptional() @IsString() description?: string; @ApiProperty({ enum: TaskStatus, default: TaskStatus.OPEN }) @IsEnum(TaskStatus) status: TaskStatus; }
استخدم @ApiPropertyOptional للحقول الاختيارية. هو اختصار لـ @ApiProperty({ required: false }) ويُبقي مزخرفات DTO موجزة. أضف قيمة example دائمًا — فهي تجعل ميزة "جرّبها الآن" مفيدة فعلًا.

@ApiResponse — توثيق أنواع البيانات المُعادة

زيّن معالجات المسارات الفردية لوصف استجابات HTTP المحتملة، بما فيها شكل البيانات المُعادة:

import { Get, Param } from '@nestjs/common'; import { ApiOkResponse, ApiNotFoundResponse, ApiUnauthorizedResponse, } from '@nestjs/swagger'; import { Task } from './task.entity'; @Get(':id') @ApiOkResponse({ type: Task, description: 'The task record' }) @ApiNotFoundResponse({ description: 'Task not found' }) @ApiUnauthorizedResponse({ description: 'Missing or invalid JWT' }) findOne(@Param('id') id: string) { return this.tasksService.findOne(id); }

بالنسبة لصنف الكيان نفسه، زيّن خصائصه بالطريقة ذاتها التي تُزيّن بها حقول DTO:

import { ApiProperty } from '@nestjs/swagger'; export class Task { @ApiProperty({ example: 'f47ac10b-58cc-4372-a567-0e02b2c3d479' }) id: string; @ApiProperty({ example: 'Write unit tests' }) title: string; @ApiProperty({ enum: TaskStatus }) status: TaskStatus; }

@ApiBearerAuth — حماية المسارات في الواجهة

حين تستلزم مسارًا توكن JWT، أضف @ApiBearerAuth() لتجعل واجهة Swagger UI ترسل التوكن من نافذة التفويض:

import { UseGuards } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; @ApiTags('tasks') @ApiBearerAuth() @UseGuards(AuthGuard('jwt')) @Controller('tasks') export class TasksController { /* ... */ }
لا تكشف Swagger في الإنتاج بلا مصادقة. يمكن تغليف استدعاء SwaggerModule.setup() بشرط مثل if (process.env.NODE_ENV !== 'production')، أو حمايته خلف HTTP basic auth. تُسرّب واجهة Swagger العامة كامل سطح API للمهاجمين.

الخلاصة

يولّد @nestjs/swagger مستند OpenAPI 3.0 مباشرةً من مزخرفاتك. ثبّت الحزمة، واستدعِ SwaggerModule.setup() في main.ts، ثم زيّن المتحكّمات بـ @ApiTags، وكائنات DTO بـ @ApiProperty، والمعالجات بمتغيّرات @ApiResponse، والمسارات المحمية بـ @ApiBearerAuth(). والنتيجة واجهة Swagger UI حيّة وتفاعلية تضاعف دورها توثيقًا قابلًا للتنفيذ لكلّ مستهلك API في فريقك.