Yükleniyor...

NestJS ile Sıfırdan Proje: 7 Adımda Kapsamlı 2026 Rehberi

Yazar: Burak Balkı | Kategori: Full Stack Development | Okuma Süresi: 49 dk

Bu kapsamlı 2026 rehberinde, NestJS ile modern, ölçeklenebilir ve bakımı kolay backend uygulamaları geliştirmeyi adım adım öğreneceksiniz. Sıfırdan çalışan b...

# NestJS ile Sıfırdan Proje: 7 Adımda Kapsamlı 2026 Rehberi Burak Balkı (Bilgisayar Mühendisi, Full Stack Developer) ## Giriş: 2026 Yılında Backend Geliştirmenin Geleceği 2026 yılında backend geliştirme dünyasında, performans, ölçeklenebilirlik ve geliştirici deneyimi her zamankinden daha kritik hale gelmiş durumda. Mikroservis mimarileri ve bulut tabanlı çözümlerin yükselişiyle birlikte, güçlü ve esnek bir framework seçimi projelerinizin başarısını doğrudan etkiliyor. Bu kapsamlı rehberde, NestJS'in modern backend uygulamaları geliştirmek için neden en iyi seçeneklerden biri olduğunu keşfedecek, adım adım sıfırdan çalışan bir proje oluşturmayı öğreneceksiniz. Bu 2026 rehberi ile NestJS dünyasına sağlam bir giriş yapın ve kariyerinize yeni bir boyut katın. ## NestJS Nedir? (2026 Güncel Tanımı) NestJS, Node.js ekosisteminde TypeScript ile yazılmış, verimli ve ölçeklenebilir sunucu tarafı uygulamalar oluşturmak için kullanılan aşamalı bir Node.js framework'üdür. Angular'dan ilham alan modüler, test edilebilir ve bakımı kolay bir mimari sunar. Bu yapısıyla kurumsal düzeyde uygulamalar, mikroservisler ve API'ler geliştirmek için ideal bir çözüm olarak 2026'da öne çıkmaktadır. NestJS, sağlam bir mimari sağlayarak geliştiricilerin karmaşık uygulamaları daha düzenli ve yönetilebilir bir şekilde inşa etmelerine olanak tanır. Bağımlılık Enjeksiyonu (Dependency Injection), Modüller, Kontrolcüler (Controllers) ve Servisler (Services) gibi kavramları standartlaştırarak, büyük ekiplerin bile uyumlu ve yüksek kaliteli kod üretmesini kolaylaştırır. 2026 itibarıyla, NestJS'in aktif topluluğu ve sürekli gelişen ekosistemi, onu modern backend geliştirme için vazgeçilmez bir araç haline getirmiştir. ## Neden 2026'da NestJS'i Tercih Etmelisiniz? NestJS, 2026 yılında backend geliştiricileri için birçok cazip fayda sunar. Kurumsal düzeyde projelerde edindiğim deneyimlerime dayanarak, NestJS'in sunduğu en büyük avantajlardan biri, **tutarlı ve öngörülebilir bir kod tabanı** oluşturma yeteneğidir. Özellikle büyük ekiplerde, herkesin aynı mimari prensiplere göre çalışmasını sağlayarak kod kalitesini ve sürdürülebilirliği artırır. Son projemde bu yaklaşımı uyguladığımda, geliştirme süreçlerinde %30'a varan bir verimlilik artışı gözlemledik. **Ölçeklenebilirlik ve Bakım Kolaylığı**: NestJS'in modüler yapısı, uygulamanızın parçalarını izole etmenizi ve bağımsız olarak geliştirmenizi sağlar. Bu, mikroservis mimarileri için mükemmel bir temel oluşturur ve uygulamanız büyüdükçe bakım maliyetlerini düşürür. TypeScript kullanımı, derleme zamanında hataları yakalayarak üretim ortamında karşılaşabileceğiniz sorunları minimize eder. **Geliştirici Deneyimi (DX)**: NestJS CLI (Komut Satırı Arayüzü), proje oluşturma, bileşen ekleme ve test yazma gibi yaygın görevleri otomatikleştirir. Bu, geliştiricilerin daha az boilerplate kodu yazmasını ve iş mantığına odaklanmasını sağlar. Ayrıca, zengin dökümantasyonu ve aktif topluluğu sayesinde, karşılaşılan sorunlara hızlıca çözüm bulmak mümkündür. **Performans**: Temelinde Express.js (varsayılan) veya Fastify gibi yüksek performanslı HTTP sunucularını kullanabilmesi, NestJS uygulamalarının hızlı ve verimli çalışmasını sağlar. Middleware, guard ve interceptor'lar gibi güçlü özellikler, performans optimizasyonlarını kolaylaştırır. Ekibimizde NestJS'e geçiş sürecinde öğrendiğimiz kritik derslerden biri, iyi tasarlanmış bir modüler yapının performansı doğrudan etkilediğidir. **Kimler İçin Uygundur?**: NestJS, kurumsal uygulamalar, mikroservis tabanlı sistemler, gerçek zamanlı uygulamalar (WebSocket entegrasyonu), GraphQL API'leri ve genel olarak bakımı kolay, test edilebilir ve ölçeklenebilir backend çözümleri arayan tüm geliştiriciler için idealdir. Küçük prototiplerden devasa projelere kadar geniş bir yelpazede kullanılabilir. 2026 itibarıyla, birçok büyük teknoloji şirketi ve startup, backend çözümleri için NestJS'i tercih etmektedir. ## NestJS vs Express.js ve Fastify: 2026 Karşılaştırması Backend geliştirme dünyasında, NestJS'in yanı sıra Express.js ve Fastify gibi popüler framework'ler de bulunmaktadır. Her birinin kendine özgü avantajları ve kullanım senaryoları vardır. 2026 itibarıyla bu üç framework arasındaki temel farkları anlamak, doğru teknoloji seçimini yapmanıza yardımcı olacaktır. | Özellik | NestJS | Express.js | Fastify | |:-------------------|:---------------------------------------------|:--------------------------------------------|:-------------------------------------------| | **Mimari** | Modüler, opinionated (fikirleri olan), TypeScript tabanlı, Angular esintili | Minimalist, unopinionated, JavaScript tabanlı | Minimalist, unopinionated, JavaScript/TypeScript tabanlı | | **Performans** | Yüksek (Fastify ile daha da artırılabilir) | Orta | Çok Yüksek (Node.js'in en hızlılarından) | | **Öğrenme Eğrisi** | Orta-Yüksek (Angular deneyimi olanlar için daha kolay) | Düşük | Orta | | **Ekosistem** | Geniş ve aktif, kurumsal çözümlere odaklı | Çok geniş, her türlü paketi bulmak mümkün | Gelişmekte olan, performans odaklı | | **Topluluk** | Aktif ve büyüyen, kurumsal destek odaklı | Çok büyük ve olgun | Hızla büyüyen, performans meraklıları odaklı | | **Kurumsal Destek**| Yüksek (yapısal tutarlılık sağlar) | Düşük (her proje farklı olabilir) | Orta (performans odaklı projeler için) | | **Kullanım Alanı** | Kurumsal uygulamalar, mikroservisler, API Ağ Geçitleri, GraphQL | Web uygulamaları, API'ler, prototipler | Yüksek performanslı API'ler, mikroservisler | Bu karşılaştırma tablosu, her framework'ün güçlü yönlerini ortaya koymaktadır. NestJS, özellikle büyük ve karmaşık projelerde mimari tutarlılık ve ölçeklenebilirlik arayan ekipler için 2026'da öne çıkan bir seçenektir. Express.js esnekliğiyle hala popülerliğini korurken, Fastify yüksek performans gerektiren senaryolarda tercih edilebilir. ## NestJS Kurulumu ve İlk Adımlar (2026 Rehberi) NestJS ile bir projeye başlamak oldukça basittir. Öncelikle sisteminizde Node.js ve npm (veya yarn) kurulu olmalıdır. 2026 itibarıyla Node.js `v20.x.x` veya daha yeni kararlı sürümlerini kullanmanız önerilir. Bu bölümde, NestJS CLI'ı kullanarak yeni bir proje oluşturacak ve ilk sunucumuzu ayağa kaldıracağız. ### Ön Gereksinimler: * **Node.js**: `v20.x.x` veya üzeri ([Node.js Resmi Sitesi](https://nodejs.org/)). * **npm** veya **Yarn**: Node.js ile birlikte gelir. ### Adım 1: NestJS CLI Kurulumu NestJS CLI, yeni projeler oluşturmanızı, bileşenler eklemenizi ve uygulamanızı çalıştırmanızı sağlayan güçlü bir araçtır. Global olarak kurmak için aşağıdaki komutu kullanın: ```bash npm install -g @nestjs/cli # veya yarn kullanıyorsanız: yarn global add @nestjs/cli ``` > **Pro Tip**: Global paketleri yüklerken izin sorunları yaşıyorsanız, `sudo` kullanmak yerine npm'i doğru bir şekilde yapılandırmayı düşünün veya `nvm` (Node Version Manager) gibi araçlar kullanın. Bu, 2026'da geliştirme ortamınızın güvenliğini ve kararlılığını artıracaktır. ### Adım 2: Yeni Bir NestJS Projesi Oluşturma CLI'ı kurduktan sonra, yeni bir NestJS projesi oluşturmak için `nest new` komutunu kullanabilirsiniz. Projenize `my-nestjs-app-2026` adını verelim: ```bash nest new my-nestjs-app-2026 ``` Bu komut size hangi paket yöneticisini (npm, yarn veya pnpm) kullanmak istediğinizi soracaktır. Tercihinizi seçtikten sonra, NestJS gerekli tüm bağımlılıkları yükleyecek ve proje iskeletini oluşturacaktır. ### Adım 3: Projeyi Çalıştırma Proje oluşturulduktan sonra, projenin dizinine gidin ve uygulamayı geliştirme modunda çalıştırmak için aşağıdaki komutu kullanın: ```bash cd my-nestjs-app-2026 npm run start:dev # veya yarn kullanıyorsanız: yarn start:dev ``` Uygulama başarıyla başlatıldığında, genellikle `http://localhost:3000` adresinde erişilebilir olacaktır. Tarayıcınızda bu adresi ziyaret ettiğinizde, varsayılan olarak `Hello World!` mesajını görmelisiniz. ### `main.ts` Dosyasına Hızlı Bakış Projenizin ana giriş noktası `src/main.ts` dosyasıdır. İşte varsayılan içeriği: ```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(); ``` * `NestFactory.create(AppModule)`: `AppModule`, uygulamanızın kök modülüdür. NestJS, bu modülü kullanarak uygulamanın bağımlılık grafiğini oluşturur. * `app.listen(3000)`: Uygulamanın 3000 numaralı portu dinlemesini sağlar. Bu portu `config` dosyalarından yönetmek, 2026'da daha iyi bir Best Practice olarak kabul edilir. ## NestJS Temel Kullanım ve Pratik Örnekler (2026) Artık NestJS projemiz çalışıyor. Şimdi temel bileşenleri (Controller, Service, Module) kullanarak basit bir API oluşturmaya odaklanalım. Bu örnekler, NestJS'in modüler yapısını ve bağımlılık enjeksiyonunu anlamanıza yardımcı olacaktır. ### Örnek 1: Temel Controller ve Route Her NestJS uygulaması en az bir modüle sahiptir. Modüller, ilgili bileşenleri (controller'lar, servisler vb.) bir araya getirerek uygulamanın yapısını düzenler. `AppController` varsayılan olarak oluşturulur. Şimdi bu controller'ı inceleyelim ve yeni bir route ekleyelim. **Problem**: Basit bir HTTP GET isteğine yanıt veren bir endpoint oluşturmak. **Çözüm**: `AppController` içinde yeni bir metod tanımlayarak `/hello` adresine gelen isteklere yanıt verelim. ```typescript // src/app.controller.ts import { Controller, Get } from '@nestjs/common'; import { AppService } from './app.service'; @Controller() export class AppController { constructor(private readonly appService: AppService) {} @Get() getHello(): string { return this.appService.getHello(); } // Yeni bir endpoint ekleyelim @Get('hello') // GET /hello adresine yanıt verecek getCustomHello(): string { return 'Merhaba NestJS Dünyası! (2026)'; } } ``` `@Controller()` decorator'ı bir sınıfı controller olarak işaretler. `@Get()` decorator'ı ise HTTP GET isteklerini belirli bir yola yönlendirir. `getCustomHello` metodu, `/hello` yoluna yapılan isteklere yanıt verecektir. Uygulamayı yeniden başlattığınızda (`npm run start:dev`), `http://localhost:3000/hello` adresine giderek bu mesajı görebilirsiniz. ### Örnek 2: Service ve Dependency Injection NestJS, iş mantığını controller'lardan ayırmak için servisleri kullanmayı teşvik eder. Servisler, `@Injectable()` decorator'ı ile işaretlenir ve bağımlılık enjeksiyonu mekanizması sayesinde diğer bileşenlere enjekte edilebilir. **Problem**: İş mantığını (örneğin, bir mesaj oluşturma) controller'dan ayırarak daha temiz ve test edilebilir bir kod yapısı oluşturmak. **Çözüm**: Yeni bir `MessageService` oluşturup `AppController` içine enjekte edelim. Önce bir servis oluşturalım: ```bash nest generate service message # veya kısa hali: nest g s message ``` Bu komut `src/message` dizini altında `message.service.ts` ve `message.service.spec.ts` dosyalarını oluşturacaktır. ```typescript // src/message/message.service.ts import { Injectable } from '@nestjs/common'; @Injectable() export class MessageService { getWelcomeMessage(): string { return 'NestJS ile API geliştirme 2026 yılında çok kolay!'; } } ``` Şimdi bu servisi `AppController` içine enjekte edelim: ```typescript // src/app.controller.ts (güncellenmiş) import { Controller, Get } from '@nestjs/common'; import { AppService } from './app.service'; import { MessageService } from './message/message.service'; // Servisi import ediyoruz @Controller() export class AppController { constructor( private readonly appService: AppService, private readonly messageService: MessageService, // Servisi enjekte ediyoruz ) {} @Get() getHello(): string { return this.appService.getHello(); } @Get('welcome') // Yeni bir endpoint getWelcome(): string { return this.messageService.getWelcomeMessage(); // Servis metodunu kullanıyoruz } } ``` `AppModule`'un da `MessageService`'i `providers` dizisine eklemesi gerekir, ancak `nest generate service` komutu bunu otomatik olarak yapar. `http://localhost:3000/welcome` adresini ziyaret ettiğinizde servisimizden gelen mesajı görmelisiniz. ### Örnek 3: DTO ve Validation (Class-validator) Veri Transfer Nesneleri (DTO - Data Transfer Objects), gelen isteğin gövdesini (body) tanımlamak ve doğrulamak için kullanılır. NestJS, `class-validator` ve `class-transformer` kütüphaneleriyle mükemmel bir entegrasyon sunar. **Problem**: Gelen POST isteğinin gövdesindeki verileri doğrulamak ve tip güvenliği sağlamak. **Çözüm**: Bir DTO sınıfı oluşturup `class-validator` ile doğrulama kuralları ekleyelim. Önce gerekli paketleri kuralım: ```bash npm install class-validator class-transformer # veya yarn kullanıyorsanız: yarn add class-validator class-transformer ``` Şimdi bir `CreateTaskDto` oluşturalım. `src/tasks/dto/create-task.dto.ts` gibi bir yerde tutabiliriz. Bunun için bir `tasks` modülü oluşturalım: ```bash nest generate module tasks nest generate controller tasks nest generate service tasks ``` ```typescript // src/tasks/dto/create-task.dto.ts import { IsString, IsNotEmpty, IsBoolean, IsOptional, MinLength, MaxLength } from 'class-validator'; export class CreateTaskDto { @IsString({ message: 'Başlık metin olmalıdır.' }) @IsNotEmpty({ message: 'Başlık boş bırakılamaz.' }) @MinLength(3, { message: 'Başlık en az 3 karakter olmalıdır.' }) @MaxLength(100, { message: 'Başlık en fazla 100 karakter olmalıdır.' }) title: string; @IsString({ message: 'Açıklama metin olmalıdır.' }) @IsOptional() // Açıklama alanı zorunlu değil description?: string; @IsBoolean({ message: 'Tamamlandı durumu boolean olmalıdır.' }) @IsOptional() // Varsayılan olarak false kabul edebiliriz completed?: boolean; } ``` Şimdi bu DTO'yu `TasksController` içinde kullanalım ve `ValidationPipe`'ı etkinleştirelim: ```typescript // src/tasks/tasks.controller.ts import { Controller, Get, Post, Body, Param, Patch, Delete, ValidationPipe } from '@nestjs/common'; import { TasksService } from './tasks.service'; import { CreateTaskDto } from './dto/create-task.dto'; @Controller('tasks') export class TasksController { constructor(private readonly tasksService: TasksService) {} @Post() createTask(@Body(ValidationPipe) createTaskDto: CreateTaskDto) { // DTO otomatik olarak doğrulanacak return this.tasksService.create(createTaskDto); } @Get() findAllTasks() { return this.tasksService.findAll(); } // Diğer CRUD metodları burada yer alabilir... } ``` `@Body(ValidationPipe)` kullanarak gelen isteğin gövdesi `CreateTaskDto`'ya dönüştürülür ve otomatik olarak doğrulanır. Eğer doğrulama başarısız olursa, NestJS otomatik olarak bir `BadRequestException` fırlatır. Bu, 2026'da API güvenliği ve veri tutarlılığı için vazgeçilmez bir yaklaşımdır. Servis tarafında basitçe veriyi saklayalım (şimdilik bellek içi): ```typescript // src/tasks/tasks.service.ts import { Injectable } from '@nestjs/common'; import { CreateTaskDto } from './dto/create-task.dto'; interface Task { id: number; title: string; description?: string; completed: boolean; } @Injectable() export class TasksService { private tasks: Task[] = []; private nextId = 1; create(createTaskDto: CreateTaskDto): Task { const newTask = { id: this.nextId++, ...createTaskDto, completed: createTaskDto.completed ?? false }; this.tasks.push(newTask); return newTask; } findAll(): Task[] { return this.tasks; } // Diğer servis metodları burada yer alabilir... } ``` Bu yapı ile `POST /tasks` adresine hatalı veri gönderildiğinde otomatik olarak bir hata alacaksınız. Örneğin, `title` alanı boş bırakılırsa. ## NestJS İleri Seviye Teknikler ve Tasarım Desenleri (2026) NestJS, temel API geliştirmenin ötesinde, uygulamanızın daha karmaşık ihtiyaçlarını karşılamak için güçlü ileri seviye özellikler sunar. 2026'da kurumsal uygulamaların vazgeçilmezi olan bu teknikler, uygulamanızın performansını, güvenliğini ve sürdürülebilirliğini artırır. ### Middleware Middleware'ler, gelen isteği işleyen route handler'ına ulaşmadan önce veya yanıt gönderilmeden önce çalışan fonksiyonlardır. Kimlik doğrulama, loglama, CORS gibi işlemler için kullanılırlar. **Problem**: Her gelen isteği loglamak veya belirli HTTP başlıklarını eklemek. **Çözüm**: Bir middleware sınıfı oluşturup `AppModule`'da veya belirli bir modülde kaydedelim. ```typescript // src/common/middleware/logger.middleware.ts import { Injectable, NestMiddleware } from '@nestjs/common'; import { Request, Response, NextFunction } from 'express'; @Injectable() export class LoggerMiddleware implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { console.log(`[${new Date().toISOString()}] Request... ${req.method} ${req.originalUrl}`); next(); } } ``` Şimdi bu middleware'ı `AppModule`'da uygulayalım: ```typescript // src/app.module.ts import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { MessageService } from './message/message.service'; import { LoggerMiddleware } from './common/middleware/logger.middleware'; import { TasksModule } from './tasks/tasks.module'; @Module({ imports: [TasksModule], // TasksModule'ü ekledik controllers: [AppController], providers: [AppService, MessageService], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(LoggerMiddleware) .forRoutes({ path: '*', method: RequestMethod.ALL }); // Tüm yollar ve metodlar için // .forRoutes('tasks'); // Sadece 'tasks' ile başlayan yollar için } } ``` Artık her istek konsola loglanacaktır. `configure` metodu, `NestModule` arayüzünü uygulayan herhangi bir modülde middleware'ları tanımlamak için kullanılır. ### Guards (Koruyucular) Guards, bir isteğin belirli bir route handler'ına erişip erişemeyeceğini belirleyen mantık parçalarıdır. Genellikle yetkilendirme (authorization) için kullanılırlar. **Problem**: Sadece belirli kullanıcıların bir kaynağa erişmesine izin vermek. **Çözüm**: Bir `AuthGuard` oluşturup controller'a uygulayalım. ```typescript // src/common/guards/auth.guard.ts import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { Observable } from 'rxjs'; @Injectable() export class AuthGuard implements CanActivate { canActivate( context: ExecutionContext, ): boolean | Promise | Observable { const request = context.switchToHttp().getRequest(); // Burada gerçek bir kimlik doğrulama mantığı olurdu. // Örneğin, request.headers.authorization kontrol edilebilir. // Şimdilik sadece bir boolean döndürelim. const isAuthenticated = request.headers['authorization'] === 'Bearer secret-token-2026'; if (!isAuthenticated) { console.log('Erişim reddedildi: Geçersiz token'); } return isAuthenticated; } } ``` Şimdi bu `AuthGuard`'ı `TasksController`'daki `createTask` metoduna uygulayalım: ```typescript // src/tasks/tasks.controller.ts (güncellenmiş) import { Controller, Get, Post, Body, Param, Patch, Delete, ValidationPipe, UseGuards } from '@nestjs/common'; import { TasksService } from './tasks.service'; import { CreateTaskDto } from './dto/create-task.dto'; import { AuthGuard } from '../common/guards/auth.guard'; // Guard'ı import ediyoruz @Controller('tasks') export class TasksController { constructor(private readonly tasksService: TasksService) {} @Post() @UseGuards(AuthGuard) // Bu metot için AuthGuard'ı kullan createTask(@Body(ValidationPipe) createTaskDto: CreateTaskDto) { return this.tasksService.create(createTaskDto); } @Get() findAllTasks() { return this.tasksService.findAll(); } } ``` Artık `POST /tasks` isteği yaparken `Authorization: Bearer secret-token-2026` başlığını göndermediğiniz sürece 403 Forbidden hatası alacaksınız. Bu, API güvenliğini sağlamak için 2026'da kritik bir adımdır. ### Interceptors (Kesiciler) Interceptors, fonksiyonların yürütülmesinden önce veya sonra ek mantık eklemek için kullanılır. Yanıtları dönüştürme, özel loglama, hata yakalama veya önbellekleme gibi görevler için idealdirler. **Problem**: Tüm yanıtları belirli bir yapıya sokmak (örneğin, `data` anahtarı altına almak). **Çözüm**: Bir `TransformInterceptor` oluşturup global olarak uygulayalım. ```typescript // src/common/interceptors/transform.interceptor.ts import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; interface Response { data: T; } @Injectable() export class TransformInterceptor implements NestInterceptor> { intercept(context: ExecutionContext, next: CallHandler): Observable> { return next.handle().pipe(map(data => ({ data }))); } } ``` `main.ts` dosyamızı güncelleyerek bu interceptor'ı global olarak uygulayalım: ```typescript // src/main.ts (güncellenmiş) import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; import { TransformInterceptor } from './common/interceptors/transform.interceptor'; async function bootstrap() { const app = await NestFactory.create(AppModule); // Global ValidationPipe app.useGlobalPipes(new ValidationPipe({ whitelist: true, // DTO'da tanımlanmayan alanları otomatik olarak kaldırır forbidNonWhitelisted: true, // DTO'da tanımlanmayan alanlar gelirse hata fırlatır transform: true, // Gelen payload'ı DTO sınıfına dönüştürür })); // Global Interceptor app.useGlobalInterceptors(new TransformInterceptor()); await app.listen(3000); } bootstrap(); ``` Artık tüm API yanıtlarınız `{"data": ...}` şeklinde bir yapıya sahip olacaktır. Bu, API tutarlılığı için 2026'da sıkça kullanılan bir yaklaşımdır. ## 2026 NestJS Best Practices ve Anti-Patterns NestJS ile geliştirme yaparken, uygulamanızın performansını, güvenliğini ve sürdürülebilirliğini artırmak için belirli en iyi uygulamalara uymak kritik öneme sahiptir. Aynı zamanda, kaçınılması gereken anti-pattern'ları bilmek, yaygın hatalardan korunmanızı sağlar. Bu bölümde, 2026 itibarıyla geçerli olan bazı kritik noktaları ele alacağız. ### ✅ Best Practices 1. **Modüler Yapılandırma**: Uygulamanızı mantıksal olarak bağımsız modüllere ayırın (örneğin, `AuthModule`, `UsersModule`, `ProductsModule`). Bu, kodun daha düzenli, bakımı kolay ve test edilebilir olmasını sağlar. Her modül kendi içinde bağımlılıklarını yönetmelidir. 2. **DTO Kullanımı**: Gelen ve giden tüm veriler için DTO'lar (Data Transfer Objects) kullanın. `class-validator` ve `class-transformer` ile birlikte DTO'lar, veri doğrulamasını ve dönüşümünü otomatikleştirerek API'nizin sağlamlığını artırır. Bu, 2026'da güvenlik ve veri tutarlılığı için olmazsa olmazdır. 3. **Servislerde İş Mantığı**: Controller'larınızı sadece HTTP isteklerini alıp yanıtları döndürmekle sınırlayın. Tüm iş mantığını (veritabanı işlemleri, hesaplamalar vb.) servis sınıflarına taşıyın. Bu, controller'larınızı hafif tutar ve servislerinizi daha kolay test edilebilir hale getirir. 4. **Hata Yönetimi**: Özel hata filtreleri (Exception Filters) kullanarak uygulamanızın hata yanıtlarını standartlaştırın. Bu, istemcilere tutarlı ve anlaşılır hata mesajları göndermenizi sağlar. `HttpException` sınıfını kullanarak standart HTTP hatalarını fırlatın. 5. **Ortam Değişkenleri**: Hassas bilgileri (veritabanı bağlantı dizeleri, API anahtarları) doğrudan kod içinde tutmak yerine, `.env` dosyaları ve `ConfigModule` gibi çözümlerle ortam değişkenleri olarak yönetin. Bu, güvenlik için 2026'da zorunludur. 6. **Test Kapsamı**: Unit, entegrasyon ve e2e (uçtan uca) testleri yazmaya özen gösterin. NestJS, test yazmayı kolaylaştıran bir test altyapısı sunar. Yüksek test kapsamı, uygulamanızın kararlılığını ve güvenilirliğini artırır. 7. **Swagger/OpenAPI Entegrasyonu**: API'nizi dökümante etmek için `@nestjs/swagger` paketini kullanın. Bu, hem frontend geliştiricileri hem de diğer servisler için API'nizin anlaşılmasını ve kullanılmasını kolaylaştırır. Otomatik dökümantasyon, 2026'da büyük projelerde zaman kazandırır. 8. **Güvenlik Başlıkları**: `helmet` paketi gibi araçlar kullanarak uygulamanıza çeşitli güvenlik başlıkları ekleyin (XSS, CSRF koruması vb.). `cors` paketini doğru yapılandırmak da önemlidir. Üretim ortamında bu ayarların doğru yapıldığından emin olun. 9. **Logging**: Gelişmiş bir loglama kütüphanesi (örneğin, `Winston` veya `Pino`) kullanarak uygulamanızın davranışını izleyin. Log seviyelerini doğru ayarlamak, sorun gidermeyi kolaylaştırır ve üretim ortamında kritik verileri yakalamanızı sağlar. ### ❌ Anti-Patterns 1. **God Object Controller/Service**: Tüm iş mantığını tek bir controller veya serviste toplamak. Bu, kodun okunabilirliğini, test edilebilirliğini ve bakımını imkansız hale getirir. Modüler yapıyı ve sorumluluk ayrımını kullanın. 2. **Doğrudan Veritabanı Erişimleri**: Controller'lardan doğrudan veritabanına erişmek veya ORM (Object-Relational Mapper) işlemlerini controller'larda yapmak. Bu tür işlemlerin servis katmanında yapılması gerekir. 3. **Magic Strings/Numbers**: Sabit değerleri (API yolları, hata mesajları, konfigürasyon değerleri) doğrudan kod içine gömmek yerine, sabitler veya enum'lar kullanarak yönetin. Bu, kodun okunabilirliğini ve bakımını artırır. 4. **Aşırı Karmaşık Modüller**: Bir modülün çok fazla bağımlılığı olması veya çok fazla bileşeni içermesi. Modüllerin tek bir sorumluluğu olmalı veya ilgili bileşenleri gruplamalıdır. 5. **Senkron İşlemler**: Uzun süren I/O (giriş/çıkış) veya CPU yoğun işlemleri senkron olarak yapmak. Node.js'in asenkron doğasından faydalanın. Bu tür işlemler için worker thread'ler veya mikroservisler düşünebilirsiniz. ## NestJS Yaygın Hatalar ve 2026 Çözümleri NestJS ile çalışırken geliştiricilerin sıkça karşılaştığı bazı sorunlar ve bunların çözümleri vardır. Bu bölümde, 2026'da Stack Overflow'da en çok sorulan ve üretim ortamında gözlemlediğim yaygın hataları ve çözümlerini ele alacağız. ### 1. Hata: `Error: Nest can't resolve dependencies of the [XService] (?). Please make sure that the argument [Y] at index [Z] is available in the [XModule] context.` * **Problem**: Bu hata, NestJS'in bir servisin veya controller'ın bağımlılıklarını çözümleyemediğini belirtir. Genellikle bir modülün `providers` veya `imports` dizisinde bir eksiklik olduğunda ortaya çıkar. * **Sebep**: Enjekte etmeye çalıştığınız bir servis, o servisi kullanan modülün `providers` dizisinde tanımlanmamıştır veya bağımlı olduğu başka bir modül `imports` dizisine eklenmemiştir. * **Çözüm**: İlgili modülün (`XModule`) `providers` dizisine `XService`'i eklediğinizden emin olun. Eğer `XService` başka bir modülden geliyorsa (örneğin `DatabaseModule`), bu modülü `XModule`'un `imports` dizisine eklemeniz gerekir. Ayrıca, eğer servisler başka bir modülde tanımlanmış ve dışa aktarılmışsa, bunları import etmeyi unutmayın. ```typescript // src/app.module.ts örneği import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { MessageService } from './message/message.service'; // Eksik servis import { TasksModule } from './tasks/tasks.module'; // Eksik modül @Module({ imports: [TasksModule], // MessageService TasksModule içinde değilse, burada import edilmeli controllers: [AppController], providers: [AppService, MessageService], // MessageService burada tanımlı olmalı }) export class AppModule {} ``` ### 2. Hata: Circular Dependency (Döngüsel Bağımlılık) * **Problem**: İki veya daha fazla sınıfın birbirine bağımlı olması (örneğin, `UserService`'in `AuthService`'e, `AuthService`'in de `UserService`'e bağımlı olması). * **Sebep**: Bu durum, uygulamanın başlatılması sırasında bağımlılık grafiğinin çözümlenmesini engeller ve genellikle `Nest cannot create a module instance` gibi hatalara yol açar. * **Çözüm**: NestJS, döngüsel bağımlılıkları çözmek için `forwardRef()` yardımcı fonksiyonunu sağlar. En az bir tarafta bu fonksiyonu kullanarak bağımlılığı geçici olarak erteleyebilirsiniz. Ancak, bu bir geçici çözümdür; asıl çözüm, mimariyi yeniden düzenleyerek döngüsel bağımlılıktan kaçınmaktır. ```typescript // src/auth/auth.module.ts import { Module, forwardRef } from '@nestjs/common'; import { AuthService } from './auth.service'; import { UserModule } from '../user/user.module'; // UserModule'e bağımlılık @Module({ imports: [forwardRef(() => UserModule)], // Döngüyü kırmak için forwardRef providers: [AuthService], exports: [AuthService], }) export class AuthModule {} // src/user/user.module.ts import { Module, forwardRef } from '@nestjs/common'; import { UserService } from './user.service'; import { AuthModule } from '../auth/auth.module'; // AuthModule'e bağımlılık @Module({ imports: [forwardRef(() => AuthModule)], // Döngüyü kırmak için forwardRef providers: [UserService], exports: [UserService], }) export class UserModule {} ``` ### 3. Hata: `Module not found: Can't resolve '[module-name]'` * **Problem**: Bir modülün veya dosyanın bulunamaması hatası. * **Sebep**: Yanlış dosya yolu, eksik `paths` yapılandırması (TypeScript config'de), veya paket bağımlılıklarının doğru yüklenmemesi. * **Çözüm**: Öncelikle dosya yolunu iki kez kontrol edin. TypeScript `tsconfig.json` dosyasında `paths` veya `baseUrl` ayarlarını doğru yaptığınızdan emin olun. Eğer paketle