NestJS 11 انٹرپرائز API پیٹرنز
NestJS 11 TypeScript میں پروڈکشن گریڈ APIs بنانے کے لیے جانے والے فریم ورک کے طور پر ابھرا ہے، جس میں Node.js کی خام طاقت کے ساتھ Angular-Inspired فن تعمیر کو ملایا گیا ہے۔ جب آپ انٹرپرائز پیمانے پر کام کر رہے ہوتے ہیں — لاکھوں درخواستوں کو ہینڈل کرنا، ملٹی کرایہ دار ڈیٹا کا نظم کرنا، اور درجنوں ماڈیولز کو مربوط کرنا — پہلے دن آپ جو پیٹرن منتخب کرتے ہیں وہ اس بات کا تعین کرتے ہیں کہ آیا آپ کا کوڈبیس خوبصورتی سے اسکیل کرتا ہے یا اس کے اپنے وزن میں گرتا ہے۔
یہ گائیڈ 310+ TypeScript فائلوں کے ساتھ 56-ماڈیول NestJS 11 بیک اینڈ بنانے سے حاصل کیے گئے اسباق کو حاصل کرتا ہے، جس میں ماڈیول آرگنائزیشن اور گارڈ کمپوزیشن سے لے کر ملٹی ٹینسی پیٹرن تک ہر چیز کا احاطہ کیا گیا ہے جو درحقیقت بوجھ کے نیچے ہیں۔
اہم ٹیک ویز
- استعمال کریں
forRoutes('*path')نہیںforRoutes('*')— NestJS 11 نے وائلڈ کارڈ روٹ کی مماثلت کو تبدیل کر دیا- عالمی استثنائی فلٹرز
main.tsمیں رجسٹرڈ ہونے چاہئیں،APP_FILTERکے ذریعے نہیں- کثیر کرایہ داری کے لیے ہر استفسار پرت پر
organizationIdفلٹرنگ کی ضرورت ہوتی ہے، نہ کہ صرف مڈل ویئر@Public()ڈیکوریٹر پیٹرن کھلے راستوں کے لیے گارڈز کو مکمل طور پر غیر فعال کرنے سے زیادہ محفوظ ہے- بوندا باندی کے سوالات میں کبھی بھی
sql.raw()استعمال نہ کریں — ہمیشہ پیرامیٹرائزڈsqlٹیمپلیٹ لٹریلز- ہر فیچر ماڈیول میں دوبارہ درآمد سے بچنے کے لیے ای میل موڈیول
@Global()ہونا چاہیے- Dotenv کو NestJS بوٹسٹریپس سے پہلے
main.tsمیں پہلے سے لوڈ کیا جانا چاہیے تاکہ env ریزولوشن کے مسائل سے بچا جا سکے۔- تمام عوامی اختتامی مقامات پر شرح کی حد بندی لازمی ہے —
@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 کی توثیق کو مکمل طور پر نظرانداز کرتا ہے۔ ویب ہک کنٹرولرز، ہیلتھ اینڈ پوائنٹس، اور تصنیف کے راستے سبھی اس طرز کو استعمال کرتے ہیں۔
آرگنائزیشن آئی ڈی کے ساتھ ملٹی ٹیننسی
کثیر کرایہ دار APIs کا بنیادی اصول: ہر ڈیٹا بیس کے استفسار کو 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 کو نافذ کرتی ہے۔ مڈل ویئر کی ناکامی یا فراموش شدہ ڈیکوریٹر کراس کرایہ دار ڈیٹا کو لیک نہیں کر سکتا کیونکہ ایس کیو ایل خود تنہائی کو نافذ کرتا ہے۔
عالمی استثناء کا فلٹر
تمام اختتامی نقطوں پر مستقل خرابی کے جوابات کے لیے عالمی استثنائی فلٹر کی ضرورت ہوتی ہے۔ 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 توثیق کے علاوہ، انٹرپرائز APIs کو کردار پر مبنی اجازت کی ضرورت ہے۔ ڈیکوریٹر پلس گارڈ پیٹرن کنٹرولرز کو صاف رکھتا ہے:
// 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 انجیکشن کر سکتی ہے۔ یہی نمونہ Redis، EventBus، اور کسی بھی کراس کٹنگ انفراسٹرکچر سروس کے لیے کام کرتا ہے۔
عوامی اختتامی پوائنٹس کو محدود کرنا
انٹرپرائز APIs کو روزانہ غلط استعمال کی کوششوں کا سامنا کرنا پڑتا ہے۔ 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/terminus کے ساتھ ہیلتھ چیکس
پروڈکشن APIs کو لوڈ بیلنس چیک اور مانیٹرنگ کے لیے ہیلتھ اینڈ پوائنٹس کی ضرورت ہوتی ہے۔ @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'),
]);
}
}
بوندا باندی ORM کے لیے حسب ضرورت اشارے (چونکہ ٹرمینس میں کوئی بلٹ ان نہیں ہے):
// 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 کے ساتھ مل کر، DTOs آپ کے دفاع کی پہلی لائن بن گئے:
// 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 ڈیکوریٹر توثیق کی پرت پر ڈیٹا کو معمول پر لاتے ہیں۔ خالی جگہ کو تراشنا اور ای میلز کو چھوٹا کرنا کیس کے فرق سے ڈپلیکیٹ ریکارڈز کو روکتا ہے۔
سویگر انٹیگریشن
انٹرپرائز APIs کو دستاویزات کی ضرورت ہے۔ 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 vars دستیاب نہیں ہیں
اگر آپ 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: لائف سائیکل ہکس میں async آپریشنز پر انتظار کا غائب ہونا
// 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 APIs میں ورژننگ کو کیسے ہینڈل کروں؟
NestJS 11 URI ورژننگ، ہیڈر ورژننگ، اور میڈیا ٹائپ ورژننگ کو باکس سے باہر سپورٹ کرتا ہے۔ اسے main.ts میں app.enableVersioning({ type: VersioningType.URI }) کے ساتھ فعال کریں، پھر @Version('1') کے ساتھ کنٹرولرز کو سجائیں۔ انٹرپرائز APIs کے لیے، URI ورژننگ (/v1/contacts) سب سے زیادہ واضح اور کیش کے موافق طریقہ ہے۔
NestJS میں فائل اپ لوڈز کو ہینڈل کرنے کا بہترین طریقہ کیا ہے؟
فائل اپ لوڈز کے لیے @nestjs/platform-express کو multer کے ساتھ استعمال کریں۔ 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 پے لوڈ میں شامل کریں۔ اگر آپ کو ہر درخواست پر تازہ اجازت کی ضرورت ہے تو، ڈیٹا بیس کو مارنے کے بجائے مختصر TTL کے ساتھ Redis کا استعمال کریں۔
اگلے اقدامات
بڑے پیمانے پر انٹرپرائز APIs بنانے کے لیے پہلے دن سے ہی صحیح فن تعمیر کی ضرورت ہوتی ہے۔ 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.