NestJS 11 एंटरप्राइज एपीआई पैटर्न
NestJS 11 टाइपस्क्रिप्ट में उत्पादन-ग्रेड एपीआई के निर्माण के लिए गो-टू फ्रेमवर्क के रूप में उभरा है, जो Node.js की कच्ची शक्ति के साथ कोणीय-प्रेरित वास्तुकला का संयोजन करता है। जब आप एंटरप्राइज़ पैमाने पर काम कर रहे होते हैं - लाखों अनुरोधों को संभालना, बहु-किरायेदार डेटा का प्रबंधन करना, और दर्जनों मॉड्यूल का समन्वय करना - पहले दिन आपके द्वारा चुने गए पैटर्न यह निर्धारित करते हैं कि आपका कोडबेस शानदार ढंग से स्केल करता है या अपने वजन के नीचे ढह जाता है।
यह मार्गदर्शिका 310+ टाइपस्क्रिप्ट फ़ाइलों के साथ 56-मॉड्यूल NestJS 11 बैकएंड के निर्माण से लेकर कड़ी मेहनत से प्राप्त सबक सिखाती है, जिसमें मॉड्यूल संगठन और गार्ड संरचना से लेकर बहु-किरायेदारी पैटर्न तक सब कुछ शामिल है जो वास्तव में लोड के तहत रहता है।
मुख्य बातें
forRoutes('*path')का उपयोग करें न किforRoutes('*')का - NestJS 11 ने वाइल्डकार्ड रूट मिलान को बदल दिया- वैश्विक अपवाद फ़िल्टर को
main.tsमें पंजीकृत किया जाना चाहिए,APP_FILTERके माध्यम से नहीं- मल्टी-टेनेंसी के लिए केवल मिडलवेयर ही नहीं, बल्कि प्रत्येक क्वेरी लेयर पर
organizationIdफ़िल्टरिंग की आवश्यकता होती है@Public()डेकोरेटर पैटर्न खुले मार्गों के लिए गार्ड को पूरी तरह से अक्षम करने की तुलना में अधिक सुरक्षित है- ड्रिज़ल प्रश्नों में कभी भी
sql.raw()का उपयोग न करें - हमेशा पैरामीटरयुक्तsqlटेम्पलेट अक्षर- प्रत्येक फीचर मॉड्यूल में पुनः आयात से बचने के लिए ईमेल मॉड्यूल
@Global()होना चाहिए- एनवी रिज़ॉल्यूशन समस्याओं से बचने के लिए Dotenv को NestJS बूटस्ट्रैप से पहले
main.tsमें प्रीलोड किया जाना चाहिए- सभी सार्वजनिक समापन बिंदुओं पर दर सीमित करना अनिवार्य है -
@nestjs/throttlerका उपयोग करें
बड़े पैमाने पर परियोजना संरचना
NestJS में सबसे महत्वपूर्ण वास्तुशिल्प निर्णय यह है कि आप मॉड्यूल को कैसे व्यवस्थित करते हैं। एंटरप्राइज़ पैमाने पर, app.module.ts में एक फ्लैट मॉड्यूल सूची असहनीय हो जाती है। जो पैटर्न काम करता है वह स्पष्ट निर्भरता घोषणाओं के साथ डोमेन-संचालित मॉड्यूल समूहीकरण है।
apps/api/src/
modules/
auth/
auth.module.ts
auth.controller.ts
auth.service.ts
guards/
jwt.guard.ts
roles.guard.ts
decorators/
public.decorator.ts
roles.decorator.ts
contacts/
contacts.module.ts
contacts.controller.ts
contacts.service.ts
contacts.spec.ts
dto/
create-contact.dto.ts
update-contact.dto.ts
billing/
billing.module.ts
billing.service.ts
webhook.controller.ts
shared/
filters/
global-exception.filter.ts
interceptors/
transform.interceptor.ts
pipes/
validation.pipe.ts
health/
health.controller.ts
indicators/
main.ts
app.module.ts
प्रत्येक डोमेन मॉड्यूल स्व-निहित है। shared/ निर्देशिका क्रॉस-कटिंग चिंताएं रखती है। यह पृथक्करण आपको मौजूदा कोड को छुए बिना नए डोमेन जोड़ने की सुविधा देता है।
@Public() डेकोरेटर पैटर्न
NestJS 11 वैश्विक स्तर पर JWT गार्ड लागू करता है, लेकिन आपको चुनिंदा एंडपॉइंट खुले होने चाहिए - स्वास्थ्य जांच, ऑथ कॉलबैक, वेबहुक रिसीवर। @Public() डेकोरेटर पैटर्न प्रति मार्ग गार्ड को अक्षम करने से कहीं बेहतर है।
// decorators/public.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
// guards/jwt-auth.guard.ts
import { Injectable, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import { IS_PUBLIC_KEY } from '../decorators/public.decorator';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
constructor(private reflector: Reflector) {
super();
}
canActivate(context: ExecutionContext) {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) return true;
return super.canActivate(context);
}
}
// app.module.ts
import { APP_GUARD } from '@nestjs/core';
@Module({
providers: [
{ provide: APP_GUARD, useClass: JwtAuthGuard },
{ provide: APP_GUARD, useClass: RolesGuard },
],
})
export class AppModule {}
अब @Public() से सुसज्जित कोई भी नियंत्रक विधि JWT सत्यापन को पूरी तरह से बायपास कर देती है। वेबहुक नियंत्रक, स्वास्थ्य समापन बिंदु और प्रमाणीकरण मार्ग सभी इस पैटर्न का उपयोग करते हैं।
ऑर्गेनाइज़ेशनआईडी के साथ मल्टी-टेनेंसी
मल्टी-टेनेंट एपीआई का मुख्य नियम: प्रत्येक डेटाबेस क्वेरी को organizationId द्वारा फ़िल्टर करना होगा। मिडलवेयर जो req.organizationId सेट करता है वह पर्याप्त नहीं है - एक डेवलपर फ़िल्टर लागू करना भूल जाता है जो क्रॉस-टेनेंट डेटा को उजागर करता है।
पैटर्न JWT पेलोड से organizationId को निकालने और इसे टाइप किए गए अनुरोध इंटरफ़ेस से जोड़ने का है:
// types/authenticated-request.interface.ts
import { Request } from 'express';
export interface AuthenticatedRequest extends Request {
user: {
sub: string;
email: string;
name: string;
role: 'admin' | 'support' | 'user';
organizationId: string;
};
}
// contacts/contacts.controller.ts
import { Controller, Get, Post, Body, Req } from '@nestjs/common';
import { AuthenticatedRequest } from '../../types/authenticated-request.interface';
@Controller('contacts')
export class ContactsController {
constructor(private contactsService: ContactsService) {}
@Get()
findAll(@Req() req: AuthenticatedRequest) {
return this.contactsService.findAll(req.user.organizationId);
}
@Post()
create(@Body() dto: CreateContactDto, @Req() req: AuthenticatedRequest) {
return this.contactsService.create(dto, req.user.organizationId);
}
}
// contacts/contacts.service.ts
import { db } from '@ecosire/db';
import { contacts } from '@ecosire/db/schema';
import { eq, and } from 'drizzle-orm';
@Injectable()
export class ContactsService {
async findAll(organizationId: string) {
return db
.select()
.from(contacts)
.where(eq(contacts.organizationId, organizationId))
.limit(100);
}
}
सेवा परत क्वेरी स्तर पर organizationId लागू करती है। कोई भी मिडलवेयर विफलता या भूला हुआ डेकोरेटर क्रॉस-टेनेंट डेटा लीक नहीं कर सकता क्योंकि SQL स्वयं अलगाव को लागू करता है।
वैश्विक अपवाद फ़िल्टर
सभी समापन बिंदुओं पर लगातार त्रुटि प्रतिक्रियाओं के लिए वैश्विक अपवाद फ़िल्टर की आवश्यकता होती है। NestJS 11 का HttpException पदानुक्रम अधिकांश मामलों को संभालता है, लेकिन आपको अप्रत्याशित त्रुटियों को भी पकड़ना होगा और उत्पादन में स्टैक ट्रेस को कभी भी उजागर नहीं करना होगा।
// filters/global-exception.filter.ts
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
HttpStatus,
Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
private readonly logger = new Logger(GlobalExceptionFilter.name);
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
let status = HttpStatus.INTERNAL_SERVER_ERROR;
let message = 'Internal server error';
let errors: Record<string, string[]> | undefined;
if (exception instanceof HttpException) {
status = exception.getStatus();
const exceptionResponse = exception.getResponse();
if (typeof exceptionResponse === 'string') {
message = exceptionResponse;
} else if (typeof exceptionResponse === 'object') {
const resp = exceptionResponse as Record<string, unknown>;
message = (resp.message as string) || message;
if (Array.isArray(resp.message)) {
// Validation errors from class-validator
errors = this.formatValidationErrors(resp.message as string[]);
message = 'Validation failed';
}
}
} else if (exception instanceof Error) {
this.logger.error(exception.message, exception.stack);
// Never expose stack traces in production
if (process.env.NODE_ENV !== 'production') {
message = exception.message;
}
}
response.status(status).json({
statusCode: status,
message,
errors,
path: request.url,
timestamp: new Date().toISOString(),
});
}
private formatValidationErrors(messages: string[]): Record<string, string[]> {
const errors: Record<string, string[]> = {};
for (const msg of messages) {
const [field, ...rest] = msg.split(' ');
if (!errors[field]) errors[field] = [];
errors[field].push(rest.join(' '));
}
return errors;
}
}
इसे main.ts में पंजीकृत करें:
// main.ts
import { NestFactory } from '@nestjs/core';
import { GlobalExceptionFilter } from './shared/filters/global-exception.filter';
async function bootstrap() {
// CRITICAL: Load env vars before NestJS bootstraps
require('dotenv').config({ path: join(__dirname, '..', '..', '..', '.env.local') });
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new GlobalExceptionFilter());
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
await app.listen(3001);
}
NestJS 11 रूट वाइल्डकार्ड परिवर्तन
NestJS 11 में सबसे महत्वपूर्ण परिवर्तनों में से एक वाइल्डकार्ड रूट मिलान है। यदि आप NestJS 10 से माइग्रेट कर रहे हैं, तो यह चुपचाप आपके मिडलवेयर को तोड़ देगा:
// NestJS 10 — works
consumer.apply(LoggerMiddleware).forRoutes('*');
// NestJS 11 — use '*path' instead
consumer.apply(LoggerMiddleware).forRoutes('*path');
यही बात स्वैगर सेटअप और किसी भी स्ट्रिंग-आधारित रूट पैटर्न पर लागू होती है। यह परिवर्तन मिडलवेयर पंजीकरण, रूट बहिष्करण और आपके द्वारा ग्लोब-शैली रूट मिलान का उपयोग करने वाले किसी भी स्थान को प्रभावित करता है।
भूमिका-आधारित अभिगम नियंत्रण
JWT प्रमाणीकरण से परे, एंटरप्राइज़ API को भूमिका-आधारित प्राधिकरण की आवश्यकता होती है। डेकोरेटर-प्लस-गार्ड पैटर्न नियंत्रकों को साफ रखता है:
// decorators/roles.decorator.ts
import { SetMetadata } from '@nestjs/common';
export type Role = 'admin' | 'support' | 'user';
export const ROLES_KEY = 'roles';
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);
// guards/roles.guard.ts
import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { ROLES_KEY, Role } from '../decorators/roles.decorator';
import { AuthenticatedRequest } from '../../types/authenticated-request.interface';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles) return true;
const { user } = context.switchToHttp().getRequest<AuthenticatedRequest>();
const hasRole = requiredRoles.some((role) => user.role === role);
if (!hasRole) {
throw new ForbiddenException('Insufficient permissions');
}
return true;
}
}
नियंत्रकों में उपयोग:
// For top-level module controllers — one `..`
import { Roles } from '../auth/guards/roles.guard';
// For nested sub-module controllers — two `../..`
import { Roles } from '../../auth/guards/roles.guard';
@Controller('admin/contacts')
@Roles('admin', 'support')
export class AdminContactsController {}
आयात पथ की गहराई बग का एक सामान्य स्रोत है। शीर्ष-स्तरीय मॉड्यूल नियंत्रक एक .. का उपयोग करते हैं; नेस्टेड उप-मॉड्यूल नियंत्रक दो ../.. का उपयोग करते हैं।
वैश्विक ईमेल मॉड्यूल पैटर्न
@Global() डेकोरेटर हर जगह उपयोग की जाने वाली सेवाओं के लिए दोहराव वाली आयात समस्या का समाधान करता है। ईमेल विहित उपयोग का मामला है - आप सूचनाएं भेजने वाले प्रत्येक फीचर मॉड्यूल में EmailModule आयात नहीं करना चाहते हैं।
// email/email.module.ts
import { Global, Module } from '@nestjs/common';
import { EmailService } from './email.service';
@Global()
@Module({
providers: [EmailService],
exports: [EmailService],
})
export class EmailModule {}
इसे एक बार AppModule में पंजीकृत करें:
@Module({
imports: [
EmailModule, // Global — available everywhere
ContactsModule,
BillingModule,
// ...
],
})
export class AppModule {}
अब कोई भी सेवा मॉड्यूल आयात को छुए बिना EmailService इंजेक्ट कर सकती है। यही पैटर्न रेडिस, इवेंटबस और किसी भी क्रॉस-कटिंग इंफ्रास्ट्रक्चर सेवा के लिए काम करता है।
दर सीमित सार्वजनिक समापन बिंदु
एंटरप्राइज़ एपीआई को प्रतिदिन दुरुपयोग के प्रयासों का सामना करना पड़ता है। NestJS का @nestjs/throttler गार्ड सिस्टम के साथ सफाई से एकीकृत होता है:
// app.module.ts
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
@Module({
imports: [
ThrottlerModule.forRoot([
{ name: 'short', ttl: 1000, limit: 10 },
{ name: 'medium', ttl: 60000, limit: 100 },
]),
],
providers: [
{ provide: APP_GUARD, useClass: ThrottlerGuard },
],
})
संवेदनशील मार्गों पर सख्त सीमाओं के लिए @Throttle() के साथ प्रति-समाप्ति बिंदु को ओवरराइड करें:
import { Throttle } from '@nestjs/throttler';
@Controller('auth')
export class AuthController {
@Post('exchange')
@Public()
@Throttle({ short: { ttl: 60000, limit: 5 } }) // 5 per minute
async exchangeCode(@Body() dto: ExchangeCodeDto) {
return this.authService.exchangeCode(dto.code);
}
}
@nestjs/टर्मिनस के साथ स्वास्थ्य जांच
उत्पादन एपीआई को लोड बैलेंसर जांच और निगरानी के लिए स्वास्थ्य समापन बिंदु की आवश्यकता होती है। @nestjs/terminus अंतर्निहित संकेतकों के साथ एक घोषणात्मक प्रणाली प्रदान करता है:
// health/health.controller.ts
import { Controller, Get } from '@nestjs/common';
import { HealthCheck, HealthCheckService, TypeOrmHealthIndicator } from '@nestjs/terminus';
import { Public } from '../auth/decorators/public.decorator';
import { DatabaseHealthIndicator } from './indicators/database.indicator';
import { RedisHealthIndicator } from './indicators/redis.indicator';
@Controller('health')
export class HealthController {
constructor(
private health: HealthCheckService,
private db: DatabaseHealthIndicator,
private redis: RedisHealthIndicator,
) {}
@Get()
@Public()
@HealthCheck()
check() {
return this.health.check([
() => this.db.isHealthy('database'),
() => this.redis.isHealthy('redis'),
]);
}
}
ड्रिज़ल ओआरएम के लिए कस्टम संकेतक (चूंकि टर्मिनस में कोई अंतर्निहित नहीं है):
// health/indicators/database.indicator.ts
import { Injectable } from '@nestjs/common';
import { HealthIndicator, HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus';
import { db } from '@ecosire/db';
import { sql } from 'drizzle-orm';
@Injectable()
export class DatabaseHealthIndicator extends HealthIndicator {
async isHealthy(key: string): Promise<HealthIndicatorResult> {
try {
await db.execute(sql`SELECT 1`);
return this.getStatus(key, true);
} catch (error) {
throw new HealthCheckError('Database check failed', this.getStatus(key, false));
}
}
}
डीटीओ सत्यापन पैटर्न
whitelist: true के साथ ValidationPipe आपकी सेवा परत तक पहुंचने से पहले अज्ञात गुणों को हटा देता है। class-transformer के साथ मिलकर, डीटीओ आपकी रक्षा की पहली पंक्ति बन जाते हैं:
// contacts/dto/create-contact.dto.ts
import { IsString, IsEmail, IsOptional, IsEnum, MinLength, MaxLength } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
export enum ContactType {
INDIVIDUAL = 'individual',
COMPANY = 'company',
}
export class CreateContactDto {
@ApiProperty({ example: 'Acme Corp' })
@IsString()
@MinLength(2)
@MaxLength(255)
@Transform(({ value }) => value?.trim())
name: string;
@ApiProperty({ example: '[email protected]' })
@IsEmail()
@Transform(({ value }) => value?.toLowerCase().trim())
email: string;
@ApiPropertyOptional({ enum: ContactType })
@IsOptional()
@IsEnum(ContactType)
type?: ContactType;
@ApiPropertyOptional()
@IsOptional()
@IsString()
@MaxLength(500)
notes?: string;
}
@Transform डेकोरेटर सत्यापन परत पर डेटा को सामान्यीकृत करते हैं। व्हाइटस्पेस को ट्रिम करना और ईमेल को छोटा करना डुप्लिकेट रिकॉर्ड को केस अंतर से बचाता है।
स्वैगर एकीकरण
एंटरप्राइज़ एपीआई को दस्तावेज़ीकरण की आवश्यकता है। NestJS का स्वैगर मॉड्यूल डेकोरेटर्स से OpenAPI स्पेक्स जेनरेट करता है, लेकिन सेटअप जानबूझकर होना चाहिए:
// main.ts
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('ECOSIRE API')
.setDescription('Enterprise API for ECOSIRE platform')
.setVersion('1.0')
.addBearerAuth()
.addTag('auth', 'Authentication endpoints')
.addTag('contacts', 'Contact management')
.build();
const document = SwaggerModule.createDocument(app, config);
// Only expose in non-production environments
if (process.env.NODE_ENV !== 'production') {
SwaggerModule.setup('api/docs', app, document);
}
await app.listen(3001);
}
प्रत्येक नियंत्रक विधि को @ApiOperation और @ApiResponse की आवश्यकता होती है:
@Get(':id')
@ApiOperation({ summary: 'Get contact by ID' })
@ApiResponse({ status: 200, description: 'Contact found', type: ContactResponseDto })
@ApiResponse({ status: 404, description: 'Contact not found' })
async findOne(@Param('id') id: string, @Req() req: AuthenticatedRequest) {
return this.contactsService.findOne(id, req.user.organizationId);
}
सामान्य नुकसान और समाधान
नुकसान 1: मॉड्यूल के बीच परिपत्र निर्भरता
सर्कुलर आयात एक गुप्त त्रुटि के साथ स्टार्टअप पर NestJS को क्रैश कर देता है। समाधान forwardRef() है:
@Module({
imports: [forwardRef(() => BillingModule)],
})
export class LicenseModule {}
बेहतर समाधान: साझा तर्क को तीसरे मॉड्यूल में निकालें जो दोनों परिपत्र निर्भरता के बिना आयात करते हैं।
नुकसान 2: मॉड्यूल आरंभीकरण के दौरान Env संस्करण उपलब्ध नहीं हैं
यदि आप dotenv लोड होने से पहले क्लास कंस्ट्रक्टर या प्रदाता फैक्ट्री में process.env.DATABASE_URL तक पहुंचते हैं, तो आपको undefined मिलता है। समाधान: किसी भी NestJS आयात से पहले, main.ts के शीर्ष पर dotenv लोड करें।
// main.ts — must be FIRST
import * as path from 'path';
require('dotenv').config({ path: path.join(__dirname, '..', '..', '..', '.env.local') });
// Then NestJS imports
import { NestFactory } from '@nestjs/core';
नुकसान 3: जीवनचक्र हुक में एसिंक संचालन पर प्रतीक्षा गायब
// Wrong — database connection might not be ready
@Injectable()
export class AppService implements OnModuleInit {
onModuleInit() {
this.seedDatabase(); // Not awaited!
}
}
// Correct
async onModuleInit() {
await this.seedDatabase();
}
नुकसान 4: बूंदा बांदी प्रश्नों में sql.raw() का उपयोग करना
sql.raw() पैरामीटराइजेशन को बायपास करता है और SQL इंजेक्शन वैक्टर खोलता है। हमेशा sql टेम्पलेट शाब्दिक का उपयोग करें:
// Dangerous — never do this
const result = await db.execute(sql.raw(`SELECT * FROM contacts WHERE id = '${id}'`));
// Safe — parameterized
const result = await db.execute(sql`SELECT * FROM contacts WHERE id = ${id}`);
अक्सर पूछे जाने वाले प्रश्न
मैं NestJS 11 API में वर्जनिंग को कैसे संभालूं?
NestJS 11 बॉक्स से बाहर URI वर्जनिंग, हेडर वर्जनिंग और मीडिया टाइप वर्जनिंग का समर्थन करता है। इसे main.ts में app.enableVersioning({ type: VersioningType.URI }) के साथ सक्षम करें, फिर नियंत्रकों को @Version('1') से सजाएं। एंटरप्राइज़ एपीआई के लिए, यूआरआई संस्करण (/v1/contacts) सबसे स्पष्ट और कैश-अनुकूल दृष्टिकोण है।
NestJS में फ़ाइल अपलोड को संभालने का सबसे अच्छा तरीका क्या है?
फ़ाइल अपलोड के लिए multer के साथ @nestjs/platform-express का उपयोग करें। S3 अपलोड के लिए, multer-s3 के माध्यम से एक कस्टम स्टोरेज इंजन कॉन्फ़िगर करें। हैंडलर चलने से पहले हमेशा पाइप स्तर पर फ़ाइल प्रकार और आकार को मान्य करें, और क्लाइंट द्वारा प्रदत्त MIME प्रकारों पर कभी भरोसा न करें - इसके बजाय मैजिक बाइट्स को मान्य करें।
मुझे NestJS में डेटाबेस लेनदेन की संरचना कैसे करनी चाहिए?
ड्रिज़ल ORM db.transaction(async (tx) => { ... }) के साथ लेनदेन का समर्थन करता है। लेनदेन ऑब्जेक्ट को वैश्विक db उदाहरण के बजाय सेवा विधियों पर पास करें। मल्टी-ऑपरेशन बिजनेस लॉजिक (ऑर्डर बनाएं + इन्वेंट्री घटाएं + ईमेल भेजें) के लिए, सब कुछ एक लेनदेन में लपेटें और कमिट के बाद .catch() के साथ ईमेल भेजने को नॉन-ब्लॉकिंग बनाएं।
मुझे गार्ड बनाम मिडलवेयर बनाम इंटरसेप्टर का उपयोग कब करना चाहिए?
गार्ड प्राधिकरण को संभालते हैं (क्या यह उपयोगकर्ता इस संसाधन तक पहुंच सकता है?)। मिडलवेयर क्रॉस-कटिंग अनुरोध परिवर्तन (लॉगिंग, सहसंबंध आईडी, पार्सिंग) को संभालता है। इंटरसेप्टर परिवर्तन, कैशिंग और मेट्रिक्स के लिए अनुरोध-प्रतिक्रिया चक्र को लपेटते हैं। निष्पादन क्रम है: मिडलवेयर → गार्ड → इंटरसेप्टर (पहले) → पाइप → हैंडलर → इंटरसेप्टर (बाद) → अपवाद फ़िल्टर।
मैं अलग से NestJS मॉड्यूल का परीक्षण कैसे करूं?
नकली निर्भरता के साथ एक परीक्षण सैंडबॉक्स बनाने के लिए Test.createTestingModule() का उपयोग करें। jest.fn() या vi.fn() के साथ अपनी सेवा विधियों का अनुकरण करें, और अपने डेटाबेस से स्वतंत्र रूप से नियंत्रक व्यवहार का परीक्षण करें। एकीकरण परीक्षणों के लिए, वास्तविक डेटाबेस कनेक्शन (अलग परीक्षण डेटाबेस) के साथ @nestjs/testing का उपयोग करें और प्रत्येक परीक्षण के बाद लेनदेन रोलबैक करें।
वैश्विक गार्डों के प्रदर्शन पर क्या प्रभाव पड़ता है?
ग्लोबल गार्ड हर अनुरोध पर चलते हैं, इसलिए उन्हें तेज़ रखें। JWT सत्यापन आम तौर पर 1-5ms है। गार्ड में डेटाबेस लुकअप से बचें - टोकन निर्माण के दौरान अनुमतियाँ लोड करें और उन्हें JWT पेलोड में शामिल करें। यदि आपको प्रत्येक अनुरोध पर नई अनुमतियों की आवश्यकता है, तो डेटाबेस को हिट करने के बजाय संक्षिप्त टीटीएल के साथ रेडिस का उपयोग करें।
अगले चरण
बड़े पैमाने पर एंटरप्राइज एपीआई बनाने के लिए पहले दिन से ही सही आर्किटेक्चर की आवश्यकता होती है। ECOSIRE की इंजीनियरिंग टीम ने जटिल मल्टी-टेनेंट वर्कफ़्लो, स्ट्राइप बिलिंग, लाइसेंस प्रबंधन और AI-संचालित एनालिटिक्स को संभालने वाले 56-मॉड्यूल NestJS 11 बैकएंड का निर्माण और संचालन किया है।
चाहे आपको कस्टम NestJS API, Odoo ERP एकीकरण, या पूर्ण-स्टैक एंटरप्राइज प्लेटफ़ॉर्म की आवश्यकता हो, हमारी टीम आपके प्रोजेक्ट में उत्पादन-सिद्ध पैटर्न लाती है। हमारी विकास सेवाओं का अन्वेषण करें यह देखने के लिए कि हम आपके अगले निर्माण को कैसे गति दे सकते हैं।
लेखक
ECOSIRE Research and Development Team
ECOSIRE में एंटरप्राइज़-ग्रेड डिजिटल उत्पाद बना रहे हैं। Odoo एकीकरण, ई-कॉमर्स ऑटोमेशन, और AI-संचालित व्यावसायिक समाधानों पर अंतर्दृष्टि साझा कर रहे हैं।
संबंधित लेख
API Rate Limiting: Patterns and Best Practices
Master API rate limiting with token bucket, sliding window, and fixed counter patterns. Protect your backend with NestJS throttler, Redis, and real-world configuration examples.
Data Mesh Architecture: Decentralized Data for Enterprise
A comprehensive guide to data mesh architecture—principles, implementation patterns, organizational requirements, and how it enables scalable, domain-driven data ownership.
ECOSIRE vs Big 4 Consultancies: Enterprise Quality, Startup Speed
How ECOSIRE delivers enterprise-grade ERP and digital transformation outcomes without Big 4 pricing, overhead, or timeline bloat. A direct comparison.