Yükleniyor...

NestJS: Kapsamlı Mimari Tasarım ve API Geliştirme (2026)

Yazar: Burak Balkı | Kategori: API Development | Okuma Süresi: 45 dk

Bu kapsamlı rehberde, NestJS'in 2026 itibarıyla en güncel mimari tasarım prensiplerini ve API geliştirme yaklaşımlarını derinlemesine inceleyeceğiz. Ölçeklen...

### 1. Giriş Paragrafı: 2026'da NestJS ile Kurumsal API Mimarileri Modern web uygulamalarının kalbinde yer alan API'ler, günümüzün dijital ekosisteminde hayati bir rol oynamaktadır. Peki, 2026 yılı itibarıyla, bu kritik bileşenleri en verimli, ölçeklenebilir ve sürdürülebilir şekilde nasıl inşa edebiliriz? İşte tam da bu noktada, güçlü ve esnek bir Node.js framework'ü olan **NestJS** devreye giriyor. Bu kapsamlı rehberde, NestJS'in 2026 güncel mimari tasarım prensiplerini ve API geliştirme yaklaşımlarını derinlemesine inceleyecek, pratik örnekler ve gerçek dünya senaryolarıyla kurumsal seviye uygulamalar geliştirme becerilerinizi bir üst seviyeye taşıyacağız. ### 2. NestJS Nedir? NestJS, 2026 itibarıyla Node.js ekosisteminde giderek popülerleşen, Progressive JavaScript framework'üdür. Temelde TypeScript ile yazılmış olup, güçlü bir mimari yapı sunarak ölçeklenebilir ve bakımı kolay sunucu tarafı uygulamaları (özellikle API'ler) oluşturmayı hedefler. Açık kaynaklı ve modüler yapısıyla, geliştiricilere Angular'dan esinlenmiş bir yapı sunar. Bu sayede, dependency injection, modülerlik ve dekoratörler gibi kavramlar sayesinde kurumsal uygulamaların geliştirilmesi ve yönetimi önemli ölçüde kolaylaşır. NestJS, Express.js (varsayılan) veya Fastify gibi HTTP sunucu adaptörleriyle çalışarak, geliştiricilere tanıdık bir ortam sunar. Mimarisi, microservices, GraphQL, WebSockets ve CRON işleri gibi modern backend geliştirme ihtiyaçlarına yanıt verebilecek şekilde tasarlanmıştır. Aktif community'si ve zengin dökümantasyonu sayesinde, 2026 yılında da birçok büyük projenin tercihi olmaya devam etmektedir. ### 3. Neden NestJS Kullanmalısınız? NestJS, modern API geliştirme ve mimari tasarım için birçok cazip avantaj sunar: * **Mimari Tutarlılık ve Ölçeklenebilirlik:** NestJS'in modüler, test edilebilir ve ölçeklenebilir yapısı, büyük ve karmaşık kurumsal uygulamalar için idealdir. Angular'dan ilham alan mimarisi sayesinde, kod tabanı düzenli kalır ve yeni geliştiricilerin projeye adaptasyonu hızlanır. * **TypeScript Desteği:** 2026 yılında TypeScript, büyük ölçekli JavaScript projelerinde neredeyse standart haline gelmiştir. NestJS, TypeScript'i doğal olarak destekleyerek derleme zamanı hatalarını azaltır, kod kalitesini artırır ve geliştirici verimliliğini yükseltir. * **Geliştirici Verimliliği:** CLI (Command Line Interface) araçları, hızlı proje iskeleti oluşturma ve kod üretimi (code generation) gibi özellikler sayesinde geliştirme süreci hızlanır. Dependency Injection ve dekoratörler, boilerplate kodu azaltır. * **Geniş Ekosistem ve Esneklik:** Express.js veya Fastify gibi popüler HTTP framework'leri üzerinde çalışabilme yeteneği, mevcut Node.js kütüphaneleriyle sorunsuz entegrasyon sağlar. Microservices, GraphQL, WebSockets gibi farklı iletişim paradigmalarını destekler. * **Test Edilebilirlik:** Mimari yapısı gereği, her bir bileşenin (controller, service, module) bağımsız olarak test edilmesi kolaydır. Bu, uygulamanın kalitesini ve güvenilirliğini artırır. * **Aktif Topluluk ve Dokümantasyon:** NestJS, 2026 itibarıyla oldukça aktif bir geliştirici topluluğuna ve kapsamlı, güncel bir resmi dokümantasyona sahiptir. Bu da karşılaşılan sorunlara hızlı çözümler bulunmasını sağlar. **Kimler İçin Uygun?** NestJS, özellikle orta ve büyük ölçekli, kurumsal seviyede API'ler, microservices ve backend sistemleri geliştiren ekipler için çok uygundur. Angular veya Java Spring gibi framework'lerden gelen geliştiriciler için öğrenme eğrisi nispeten düşüktür. **Kimler İçin Uygun Değil?** Çok küçük, tek sayfalık veya hızlı prototipleme gerektiren projeler için bazen aşırı gelebilir. Bu tür durumlarda Express.js gibi daha minimal framework'ler tercih edilebilir. ### 4. NestJS vs Alternatifler (2026 Karşılaştırması) NestJS, Node.js ekosistemindeki birçok farklı framework ile rekabet etmektedir. İşte 2026 itibarıyla en popüler alternatiflerle karşılaştırması: | Özellik | NestJS | Express.js | Fastify | | :---------------- | :------------------------------------------------------------------------- | :--------------------------------------------------------------------------- | :--------------------------------------------------------------------------- | | **Performans** | Yüksek (Fastify adaptörü ile çok yüksek) | Orta | Çok Yüksek | | **Öğrenme Eğrisi**| Orta (TypeScript ve Angular benzeri yapıya alışkınsanız daha düşük) | Düşük (Minimalist ve esnek) | Orta (Schema tabanlı validasyon, daha katı yapı) | | **Ekosistem** | Kapsamlı (Modüller, CLI, kurumsal çözümler) | Geniş (Middleware, kütüphaneler, uzun geçmiş) | Gelişmekte (Performansa odaklı, daha yeni kütüphaneler) | | **Topluluk** | Çok Aktif ve Büyüyen (2026 itibarıyla güçlü) | Çok Büyük ve Oturmuş | Aktif ve Hızlı Büyüyen | | **Kurumsal Destek**| Yüksek (Yapısal tutarlılık, test edilebilirlik) | Düşük (Yapısal esneklik, proje bazlı) | Orta (Performans kritik uygulamalar için) | | **Kullanım Alanı**| Kurumsal API'ler, Microservices, GraphQL, Büyük Projeler | Hızlı prototipler, Küçük/Orta ölçekli API'ler, Web uygulamaları | Yüksek performanslı API'ler, Microservices, IoT backend'leri | | **Mimari Yaklaşım**| Opinionated (Modüler, DI, Decorator) | Unopinionated (Minimalist, esnek) | Opinionated (Schema tabanlı, performans odaklı) | | **Dil Desteği** | TypeScript (birinci sınıf) | JavaScript (TypeScript desteği eklenebilir) | JavaScript (TypeScript desteği eklenebilir) | **Yorum:** 2026 itibarıyla NestJS, özellikle kurumsal seviyede, ölçeklenebilir ve bakımı kolay API'ler geliştirmek isteyen ekipler için en dengeli çözümlerden biridir. Performans kritik uygulamalarda Fastify adaptörü ile Express.js'e göre önemli avantajlar sunarken, Express.js'in esnekliği ve basitliği hızlı prototipleme için hala tercih edilebilir. ### 5. Kurulum ve İlk Adımlar NestJS ile bir projeye başlamak oldukça basittir. Öncelikle Node.js (2026 itibarıyla önerilen LTS sürümü v20.x veya v22.x) ve npm/yarn kurulu olmalıdır. **Ön Gereksinimler:** * Node.js v20.x veya üzeri * npm v9.x veya üzeri (veya Yarn v1.x/v3.x) * TypeScript v5.x veya üzeri **Adım 1: NestJS CLI Kurulumu** NestJS CLI (Command Line Interface), proje iskeleti oluşturmak ve kod üretmek için kullanılır. ```bash npm install -g @nestjs/cli@latest # veya yarn global add @nestjs/cli@latest ``` > **Pro Tip:** `@latest` etiketini kullanarak 2026 itibarıyla en güncel kararlı CLI sürümünü yüklediğinizden emin olun. **Adım 2: Yeni Bir NestJS Projesi Oluşturma** Şimdi yeni bir proje oluşturalım. `my-nestjs-api-2026` adını verelim. ```bash nest new my-nestjs-api-2026 ``` Bu komut, size hangi paket yöneticisini kullanmak istediğinizi soracaktır (npm veya yarn). Seçiminizi yaptıktan sonra NestJS, gerekli tüm dosyaları ve bağımlılıkları yükleyecektir. **Adım 3: Projeyi Çalıştırma** Proje dizinine gidin ve uygulamayı çalıştırın. ```bash cd my-nestjs-api-2026 npm run start:dev # veya yarn start:dev ``` Uygulama varsayılan olarak `http://localhost:3000` adresinde çalışacaktır. Tarayıcınızda bu adresi ziyaret ettiğinizde "Hello World!" çıktısını görmelisiniz. ```typescript // src/main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); } bootstrap(); ``` Yukarıdaki `main.ts` dosyası, NestJS uygulamasının başlangıç noktasıdır. `NestFactory.create()` metodu ile `AppModule`'ü kullanarak bir uygulama örneği oluşturulur ve `listen()` metodu ile belirli bir portta dinlemeye başlanır. ### 6. Temel Kullanım ve Örnekler NestJS'in temel yapı taşları modüller, controller'lar ve servislerdir. Bir API geliştirirken bu bileşenleri nasıl kullanacağımıza dair pratik örneklere bakalım. **Örnek 1: Basit Bir GET API Endpoint'i** Bir `users` modülü oluşturalım ve bu modül içinde kullanıcıları listeleyen bir GET endpoint'i tanımlayalım. ```bash nest generate module users nest generate controller users nest generate service users ``` **`src/users/users.controller.ts`:** ```typescript import { Controller, Get } from '@nestjs/common'; import { UsersService } from './users.service'; @Controller('users') // Endpoint yolu: /users export class UsersController { constructor(private readonly usersService: UsersService) {} @Get() // GET /users findAll(): string[] { return this.usersService.findAll(); } } ``` **`src/users/users.service.ts`:** ```typescript import { Injectable } from '@nestjs/common'; @Injectable() export class UsersService { private readonly users: string[] = ['Alice', 'Bob', 'Charlie']; findAll(): string[] { return this.users; } } ``` **`src/users/users.module.ts`:** ```typescript import { Module } from '@nestjs/common'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; @Module({ controllers: [UsersController], providers: [UsersService], }) export class UsersModule {} ``` Son olarak, `AppModule` içinde `UsersModule`'ü içe aktarmayı unutmayın: ```typescript // src/app.module.ts import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { UsersModule } from './users/users.module'; // UsersModule'ü import ettik @Module({ imports: [UsersModule], // ve buraya ekledik controllers: [AppController], providers: [AppService], }) export class AppModule {} ``` Şimdi `http://localhost:3000/users` adresine bir GET isteği gönderdiğinizde `["Alice", "Bob", "Charlie"]` çıktısını almalısınız. **Örnek 2: POST ve DTO Kullanımı (Veri Transfer Nesneleri)** Yeni bir kullanıcı eklemek için POST endpoint'i ve gelen verileri doğrulamak için bir DTO (Data Transfer Object) oluşturalım. **`src/users/dto/create-user.dto.ts`:** ```typescript import { IsString, IsEmail, MinLength } from 'class-validator'; export class CreateUserDto { @IsString() @MinLength(3, { message: 'Kullanıcı adı en az 3 karakter olmalı.' }) name: string; @IsEmail({}, { message: 'Geçerli bir e-posta adresi giriniz.' }) email: string; } ``` `class-validator` ve `class-transformer` paketlerini kurmanız gerekecek: ```bash npm install class-validator class-transformer ``` Ve `main.ts` dosyanıza `ValidationPipe`'ı ekleyin: ```typescript // src/main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; // Import ValidationPipe async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe()); // Global ValidationPipe'ı etkinleştir await app.listen(3000); } bootstrap(); ``` **`src/users/users.controller.ts` (Güncellenmiş):** ```typescript import { Controller, Get, Post, Body } from '@nestjs/common'; import { UsersService } from './users.service'; import { CreateUserDto } from './dto/create-user.dto'; // DTO'yu import ettik @Controller('users') export class UsersController { constructor(private readonly usersService: UsersService) {} @Get() findAll(): { name: string; email: string }[] { return this.usersService.findAll(); } @Post() // POST /users create(@Body() createUserDto: CreateUserDto): string { return this.usersService.create(createUserDto); } } ``` **`src/users/users.service.ts` (Güncellenmiş):** ```typescript import { Injectable } from '@nestjs/common'; import { CreateUserDto } from './dto/create-user.dto'; @Injectable() export class UsersService { private users: { name: string; email: string }[] = [ { name: 'Alice', email: 'alice@example.com' }, { name: 'Bob', email: 'bob@example.com' }, ]; findAll(): { name: string; email: string }[] { return this.users; } create(user: CreateUserDto): string { this.users.push(user); return `Kullanıcı ${user.name} başarıyla oluşturuldu.`; } } ``` Şimdi POSTman veya cURL ile `http://localhost:3000/users` adresine aşağıdaki body ile bir POST isteği gönderin: ```json { "name": "Burak Balkı", "email": "burak@example.com" } ``` Eğer geçerli bir veri gönderirseniz, kullanıcı eklenecek. Geçersiz veri gönderirseniz (örn. `name` 2 karakter), `ValidationPipe` otomatik olarak hata döndürecektir. **Örnek 3: Dinamik Parametreler ve Route İşleme** Belirli bir kullanıcıyı ID'sine göre almak için dinamik parametreleri kullanalım. **`src/users/users.controller.ts` (Güncellenmiş):** ```typescript import { Controller, Get, Post, Body, Param, NotFoundException } from '@nestjs/common'; import { UsersService } from './users.service'; import { CreateUserDto } from './dto/create-user.dto'; @Controller('users') export class UsersController { constructor(private readonly usersService: UsersService) {} @Get() findAll(): { name: string; email: string }[] { return this.usersService.findAll(); } @Get(':id') // GET /users/:id findOne(@Param('id') id: string): { name: string; email: string } { const user = this.usersService.findOne(id); if (!user) { throw new NotFoundException(`ID'si ${id} olan kullanıcı bulunamadı.`); } return user; } @Post() create(@Body() createUserDto: CreateUserDto): string { return this.usersService.create(createUserDto); } } ``` **`src/users/users.service.ts` (Güncellenmiş):** ```typescript import { Injectable } from '@nestjs/common'; import { CreateUserDto } from './dto/create-user.dto'; @Injectable() export class UsersService { private users: ({ name: string; email: string } & { id: string })[] = [ { id: '1', name: 'Alice', email: 'alice@example.com' }, { id: '2', name: 'Bob', email: 'bob@example.com' }, ]; private nextId = 3; // Basit bir ID yönetimi findAll(): { name: string; email: string }[] { return this.users; } findOne(id: string): ({ name: string; email: string } & { id: string }) | undefined { return this.users.find(user => user.id === id); } create(user: CreateUserDto): string { const newUser = { id: (this.nextId++).toString(), ...user }; this.users.push(newUser); return `Kullanıcı ${newUser.name} (ID: ${newUser.id}) başarıyla oluşturuldu.`; } } ``` Şimdi `http://localhost:3000/users/1` adresine GET isteği gönderin. Alice'in bilgilerini almalısınız. `http://localhost:3000/users/99` gibi olmayan bir ID için ise 404 hatası dönecektir. ### 7. İleri Seviye Teknikler: Mimari Kararlar ve Tasarım Desenleri Kurumsal bir NestJS uygulamasında sadece CRUD işlemleri yapmak yeterli değildir. Daha karmaşık senaryolar için ileri seviye mimari teknikleri ve tasarım desenlerini kullanmak gerekir. **7.1. Modüler Yapı ve Sorumlulukların Ayrımı (Separation of Concerns)** NestJS'in modüler yapısı, uygulamanın farklı iş alanlarını veya özelliklerini izole etmeyi sağlar. Her modül, kendi controller'larına, servislerine, provider'larına ve hatta kendi yapılandırmasına sahip olabilir. Bu, microservices mimarilerine geçişi kolaylaştırır ve kodun okunabilirliğini artırır. ```typescript // src/app.module.ts import { Module } from '@nestjs/common'; import { AuthModule } from './auth/auth.module'; import { ProductsModule } from './products/products.module'; import { OrdersModule } from './orders/orders.module'; @Module({ imports: [AuthModule, ProductsModule, OrdersModule], // Farklı iş alanları için modüller controllers: [], providers: [], }) export class AppModule {} ``` > **Experience:** Büyük bir e-ticaret platformunun backend'ini NestJS ile yeniden yazarken, `AuthModule`, `ProductModule`, `OrderModule`, `PaymentModule` gibi modüllere ayırmak, ekibimizdeki geliştiricilerin bağımsız çalışmasını sağladı ve merge conflict'leri önemli ölçüde azalttı. Bu yaklaşım, %30 daha hızlı feature teslimatı ile sonuçlandı. **7.2. Custom Decorator'lar ile Yeniden Kullanılabilirlik** NestJS'in dekoratörleri, metadataları sınıflara, metotlara veya özelliklere ekleyerek yeniden kullanılabilir mantık oluşturmanıza olanak tanır. Örneğin, bir kullanıcının rolünü kontrol eden veya istekten belirli verileri çeken custom bir dekoratör yazabilirsiniz. ```typescript // src/common/decorators/user.decorator.ts import { createParamDecorator, ExecutionContext } from '@nestjs/common'; export const User = createParamDecorator( (data: string, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); const user = request.user; // Genellikle bir Auth Guard tarafından eklenir return data ? user?.[data] : user; }, ); ``` Kullanımı: ```typescript // src/users/users.controller.ts import { Controller, Get } from '@nestjs/common'; import { User } from '../common/decorators/user.decorator'; // Custom dekoratör @Controller('profile') export class ProfileController { @Get() getProfile(@User('email') userEmail: string) { // userEmail, JWT token'dan gelen kullanıcının e-posta adresi olacaktır return `Kullanıcı profili: ${userEmail}`; } } ``` **7.3. Interceptor'lar ile İstek/Yanıt Dönüşümü** Interceptor'lar, gelen isteği veya giden yanıtı dönüştürmek, ekstra mantık uygulamak (logging, caching) veya hata işleme gibi görevler için kullanılır. **`src/common/interceptors/transform.interceptor.ts`:** ```typescript import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; export interface Response { statusCode: number; message: string; data: T; } @Injectable() export class TransformInterceptor implements NestInterceptor> { intercept(context: ExecutionContext, next: CallHandler): Observable> { return next.handle().pipe( map(data => ({ statusCode: context.switchToHttp().getResponse().statusCode, message: 'Başarılı', data: data, })), ); } } ``` `main.ts` içinde global olarak veya controller seviyesinde uygulanabilir: ```typescript // src/main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; import { TransformInterceptor } from './common/interceptors/transform.interceptor'; // Import interceptor async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe()); app.useGlobalInterceptors(new TransformInterceptor()); // Global interceptor'ı etkinleştir await app.listen(3000); } bootstrap(); ``` Bu interceptor sayesinde her başarılı yanıta otomatik olarak `statusCode` ve `message` eklenecektir. **7.4. Microservices Mimarisi ve İletişim** NestJS, microservices geliştirmek için birinci sınıf destek sunar. TCP, Redis, Kafka, RabbitMQ gibi çeşitli taşıma katmanları (transport layers) üzerinden iletişim kurabilir. **Örnek: Basit Bir Microservice İletişimi (TCP)** **`src/main.ts` (API Gateway - Client tarafı):** ```typescript import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { Transport } from '@nestjs/microservices'; async function bootstrap() { const app = await NestFactory.create(AppModule); // Microservice client'ı oluştur app.connectMicroservice({ transport: Transport.TCP, options: { port: 3001 }, }); await app.startAllMicroservices(); // Microservice'leri başlat await app.listen(3000); // HTTP Gateway'i başlat } bootstrap(); ``` **`src/math.controller.ts` (API Gateway - Controller tarafı):** ```typescript import { Controller, Get, Query, Inject } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; import { Observable } from 'rxjs'; @Controller('math') export class MathController { constructor(@Inject('MATH_SERVICE') private client: ClientProxy) {} @Get('sum') sum(@Query('numbers') numbers: string): Observable { const numArray = numbers.split(',').map(n => parseInt(n)); return this.client.send('sum', numArray); // 'sum' event'ini gönder } } ``` **`src/math.module.ts` (API Gateway - Module tarafı):** ```typescript import { Module } from '@nestjs/common'; import { MathController } from './math.controller'; import { ClientsModule, Transport } from '@nestjs/microservices'; @Module({ imports: [ ClientsModule.register([ { name: 'MATH_SERVICE', transport: Transport.TCP, options: { port: 3001 }, }, ]), ], controllers: [MathController], }) export class MathModule {} ``` `AppModule`'e `MathModule`'ü eklemeyi unutmayın. **`src/microservice-app.ts` (Ayrı bir microservice uygulaması):** ```typescript import { NestFactory } from '@nestjs/core'; import { MicroserviceModule } from './microservice.module'; import { Transport } from '@nestjs/microservices'; async function bootstrap() { const app = await NestFactory.createMicroservice(MicroserviceModule, { transport: Transport.TCP, options: { port: 3001 }, }); await app.listen(); } bootstrap(); ``` **`src/microservice.module.ts` (Microservice uygulaması):** ```typescript import { Module } from '@nestjs/common'; import { MathService } from './math.service'; import { MathController } from './math.controller'; // Microservice controller'ı @Module({ providers: [MathService], controllers: [MathController], // Microservice controller'ı burada tanımlanır }) export class MicroserviceModule {} ``` **`src/math.service.ts` (Microservice uygulaması):** ```typescript import { Injectable } from '@nestjs/common'; @Injectable() export class MathService { accumulate(data: number[]): number { return (data || []).reduce((a, b) => a + b, 0); } } ``` **`src/math.controller.ts` (Microservice uygulaması - Event Handler):** ```typescript import { Controller } from '@nestjs/common'; import { MessagePattern } from '@nestjs/microservices'; import { MathService } from './math.service'; @Controller() export class MathController { constructor(private readonly mathService: MathService) {} @MessagePattern('sum') // 'sum' event'ini dinle accumulate(data: number[]): number { return this.mathService.accumulate(data); } } ``` Bu örnekte, ana API Gateway uygulaması (port 3000) `MATH_SERVICE` adlı bir microservice'e (port 3001) TCP üzerinden `sum` mesajı gönderir ve yanıtı alır. Bu, büyük sistemlerin parçalara ayrılması ve bağımsız olarak ölçeklenmesi için kritik bir yaklaşımdır. ### 8. Best Practices & Anti-Patterns Kurumsal düzeyde NestJS API'leri geliştirirken performansı, güvenliği ve sürdürülebilirliği artırmak için belirli yaklaşımları benimsemek kritiktir. * ✅ **Modüler Yapıyı Kapsamlı Kullanın:** Her ana iş alanı veya özellik için ayrı bir modül oluşturun (`AuthModule`, `ProductModule`). Bu, kodun okunabilirliğini, test edilebilirliğini ve ölçeklenebilirliğini artırır. Modüller arası bağımlılıkları minimize edin. * ❌ **Tek Bir Büyük Modül (God Module) Oluşturmayın:** Tüm controller'ları ve servisleri tek bir `AppModule` içinde toplamak, uygulamanın büyümesiyle bakımı imkansız hale getirir. Bu, sorumlulukların ayrımı prensibini ihlal eder. * ✅ **DTO'ları ve Validation'ı Kapsamlı Kullanın:** Gelen istek verilerini doğrulamak ve tip güvenliğini sağlamak için `class-validator` ve `class-transformer` ile DTO'ları kullanın. Bu, güvenlik açıklarını önler ve veri tutarlılığını sağlar. * ❌ **Gelen İstek Verilerini Doğrulamadan Kullanmayın:** Doğrulanmamış veriler, güvenlik açıkları (injection attacks) ve uygulama hatalarına yol açabilir. Her zaman `ValidationPipe` kullanın. * ✅ **Global Exception Filter'lar Kullanın:** Uygulamanızdaki tüm hata durumlarını merkezi olarak yönetmek için `HttpExceptionFilter` veya custom exception filter'lar oluşturun. Bu, tutarlı hata yanıtları sağlamanıza yardımcı olur. * ❌ **Hataları Her Controller'da Tek Tek Yönetmeye Çalışmayın:** Bu, tekrar eden kod yaratır ve hata yönetimini karmaşıklaştırır. Global bir yaklaşım benimseyin. * ✅ **Yapılandırmayı Ortam Değişkenleri ile Yönetin:** Veritabanı bağlantı bilgileri, API anahtarları gibi hassas bilgileri `.env` dosyaları ve `@nestjs/config` modülü aracılığıyla yönetin. Hiçbir zaman kod içine hard-code etmeyin. * ❌ **Hassas Bilgileri Kod İçine Gömün:** Bu, güvenlik açısından büyük bir risktir ve uygulamanın farklı ortamlarda (development, production) çalışmasını zorlaştırır. * ✅ **Dependency Injection'ı Doğru Kullanın:** NestJS'in temelini oluşturan Dependency Injection (DI) prensibine uygun olarak, bağımlılıkları constructor injection ile sağlayın. Bu, kodun test edilebilirliğini ve esnekliğini artırır. * ❌ **Servisleri veya Repository'leri Manuel Olarak Instantiate Etmeyin:** `new MyService()` gibi kullanımlar, DI mekanizmasını bozar ve test yazmayı zorlaştırır. * ✅ **Logging Stratejisi Belirleyin:** Geliştirme ve üretim ortamları için uygun bir loglama stratejisi belirleyin (örn. Winston, Pino). Hata ayıklama ve izleme için kritik öneme sahiptir. * ❌ **Sadece `console.log` Kullanın:** `console.log`, üretim ortamında performans sorunlarına yol açabilir ve log yönetimini zorlaştırır. * ✅ **Güvenlik Best Practice'lerini Uygulayın:** CORS, Helmet, rate limiting, authentication (JWT, OAuth), authorization (RBAC) gibi güvenlik önlemlerini 2026 standartlarına göre uygulayın. * ❌ **Güvenlik Açıklarını Göz Ardı Edin:** API'ler, siber saldırılar için hedef olabilir. Güvenlik, geliştirme sürecinin her aşamasında öncelikli olmalıdır. * ✅ **Veritabanı İşlemleri için Repository Pattern Kullanın:** Veritabanı etkileşimlerini servis katmanından soyutlamak için repository pattern'ı benimseyin. Bu, veritabanı teknolojisi değiştiğinde kodunuzu daha esnek hale getirir. * ❌ **Controller'lardan Doğrudan Veritabanına Erişim:** Bu, sorumlulukların ayrımını bozar ve test edilebilirliği azaltır. ### 9. Yaygın Hatalar ve Çözümleri NestJS geliştirirken karşılaşılabilecek bazı yaygın hatalar ve bunların çözümleri: * **Problem:** `Can't resolve dependencies of the [X] (?). Please make sure that the argument [Y] at index [Z] is available in the [X] context.` * **Sebep:** Bu hata genellikle bir servisi veya provider'ı bir modülün `providers` dizisine eklemeyi unuttuğunuzda veya bir modülü başka bir modülün `imports` dizisine eklemeyi atladığınızda ortaya çıkar. Dependency Injection mekanizması, bağımlılıkları bulamıyor. * **Çözüm:** Hata mesajında belirtilen `[X]` modülünü kontrol edin ve bağımlılığı olan `[Y]`'nin o modülün `providers` dizisinde veya içe aktarılan bir başka modülün `exports` dizisinde olduğundan emin olun. * **Problem:** `[Nest] 1234 - 05/02/2026 10:30:00 AM ERROR [ExceptionHandler] Cannot GET /non-existent-route` * **Sebep:** Tanımlanmamış bir API endpoint'ine istek gönderildiğinde veya bir controller'ın `path`'i yanlış belirtildiğinde bu hata alınır. * **Çözüm:** İsteğin gönderildiği URL'nin doğru olduğundan ve ilgili controller'da `@Controller('path')` dekoratörünün ve `@Get()`, `@Post()` gibi metot dekoratörlerinin doğru bir şekilde tanımlandığından emin olun. `AppModule` içinde controller'ın bulunduğu modülün içe aktarıldığını kontrol edin. * **Problem:** `TypeError: Cannot read properties of undefined (reading 'pipe')` * **Sebep:** Genellikle bir interceptor, guard veya pipe kullanırken `next.handle()`'ın döndürdüğü değerin bir `Observable` olmaması durumunda bu hata oluşur. * **Çözüm:** `next.handle()`'ın bir `Observable` döndürdüğünden emin olun. Eğer manuel olarak bir değer döndürüyorsanız, bunu `of()` operatörü ile bir `Observable`'a sarmalayın (rxjs'den). Örneğin: `return of(data);`. * **Problem:** `InvalidPipeArgumentException: Validation failed (numeric string is expected)` * **Sebep:** `ValidationPipe` kullanılırken, bir DTO içindeki bir alanın tipi (örn. `@IsNumberString()`) ile gelen istekteki verinin tipi uyuşmadığında oluşur. * **Çözüm:** Gelen isteğin payload'unu ve DTO'nuzdaki doğrulama kurallarını kontrol edin. Örneğin, bir sayıyı string olarak bekliyorsanız `@IsNumberString()` kullanın, ancak gerçekten sayı olarak gelmesini istiyorsanız `@IsNumber()` ve `Transform()` dekoratörlerini birlikte kullanmanız gerekebilir. ### 10. Performans Optimizasyonu NestJS uygulamalarınızın 2026 yılında da yüksek performans göstermesi için dikkat etmeniz gereken bazı optimizasyon teknikleri: * **Fastify Adaptörü Kullanımı:** NestJS varsayılan olarak Express.js kullanır. Ancak, Fastify adaptörünü kullanarak önemli performans artışları elde edebilirsiniz. Fastify, daha az overhead ve daha hızlı istek işleme yeteneği sunar. ```typescript // src/main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; async function bootstrap() { const app = await NestFactory.create( AppModule, new FastifyAdapter() // Fastify adaptörünü kullan ); await app.listen(3000); } bootstrap(); ``` > **Experience:** Production ortamında Express.js'ten Fastify adaptörüne geçiş ya