# 2026'da NestJS ile Mikroservisler: Mimari, gRPC ve Mülakat Soruları > gRPC ile NestJS mikroservis mimarisine yönelik pratik bir rehber: servis sınırları, taşıma katmanları, akış desenleri ve 2026 için sık karşılaşılan mülakat soruları. - Published: 2026-05-26 - Updated: 2026-05-27 - Author: SharpSkill - Tags: nestjs, microservices, grpc, nodejs, typescript, architecture - Reading time: 9 min --- NestJS mikroservisleri, 2026'da dağıtık Node.js arka uçları kurmanın standart yaklaşımı haline geldi. NestJS 11'in geliştirilmiş taşıyıcı katmanı, birinci sınıf gRPC desteği ve otomatik trace ID yayılımı sayesinde framework, geliştirici deneyiminden ödün vermeden bir monolitin iyi sınırlandırılmış servislere bölünmesi için gereken her şeyi sağlar. > **Dahili servisler için gRPC ve REST karşılaştırması** > > gRPC, Protocol Buffers ve HTTP/2 kullanır; REST üzerinden JSON'a kıyasla 10 kata kadar daha hızlı serileştirme ve yerel çift yönlü akış sunar. Bir küme içindeki servisten servise iletişimde gRPC, gecikmeyi azaltır ve `.proto` dosyaları aracılığıyla katı sözleşmeleri zorunlu kılar. REST, tarayıcılar ve üçüncü taraflarca tüketilen herkese açık API'ler için daha iyi bir seçim olmaya devam eder. ## NestJS Mikroservis Taşıma Katmanı Mimarisi `@nestjs/microservices` paketi, HTTP denetleyicilerini mesaj odaklı işleyicilerle değiştirir. URL yoluna göre yönlendirme yerine her işleyici bir **mesaj desenine** (message pattern) yanıt verir — bu, işlemi tanımlayan bir dize ya da nesne anahtarıdır. Bu soyutlama sayesinde aynı işleyici mantığı, kod değişikliği olmadan TCP, Redis, NATS, Kafka, RabbitMQ veya gRPC üzerinde çalışır. NestJS 11, tüm taşıyıcılarda alttaki istemci örneğine doğrudan erişim sağlayan `unwrap()` yöntemini tanıttı. Bu, uzun süredir devam eden bir sıkıntıyı çözer: bağlantı durumunu incelemek, keepalive aralıklarını ayarlamak veya NestJS soyutlamasının açığa çıkarmadığı aracıya özgü özelliklere erişmek. NestJS mikroservislerini iki iletişim deseni yönlendirir: - **İstek-yanıt** (`@MessagePattern`): istemci bir mesaj gönderir ve bir yanıt bekler. Kullanıcı profili getirme veya bir token'ı doğrulama gibi senkron sorgular için uygundur. - **Olay tabanlı** (`@EventPattern`): istemci bir olay yayar ve devam eder — yanıt beklenmez. Denetim günlükleri, bildirimler veya alt akış iş akışlarını tetiklemek için idealdir. ```typescript // orders.controller.ts import { Controller } from '@nestjs/common'; import { MessagePattern, EventPattern, Payload } from '@nestjs/microservices'; import { OrdersService } from './orders.service'; import { CreateOrderDto } from './dto/create-order.dto'; @Controller() export class OrdersController { constructor(private readonly ordersService: OrdersService) {} // Request-response: caller waits for the created order @MessagePattern('order.create') async createOrder(@Payload() data: CreateOrderDto) { return this.ordersService.create(data); } // Event-based: fire and forget, no response returned @EventPattern('order.shipped') async handleOrderShipped(@Payload() data: { orderId: string }) { await this.ordersService.markAsShipped(data.orderId); } } ``` `@MessagePattern` işleyicisi, dönüş değerini otomatik olarak serileştirir ve taşıma üzerinden geri gönderir. `@EventPattern` işleyicisi hiçbir şey döndürmez — NestJS herhangi bir dönüş değerini atar. ## gRPC'yi NestJS Mikroservis Taşıması Olarak Yapılandırmak NestJS'te gRPC entegrasyonu, servis sözleşmesini tanımlayan bir `.proto` dosyasıyla başlar. Protocol Buffers, kablo düzeyinde tür güvenliğini zorunlu kılar — hem istemci hem de sunucu, tek bir bayt ağdan geçmeden önce her mesajın tam biçimi üzerinde anlaşmalıdır. ```protobuf // proto/users.proto syntax = "proto3"; package users; service UsersService { rpc FindOne (UserById) returns (User); rpc FindMany (UserFilter) returns (stream User); } message UserById { string id = 1; } message UserFilter { string role = 1; int32 limit = 2; } message User { string id = 1; string email = 2; string name = 3; string role = 4; } ``` Sunucu tarafında NestJS uygulaması, proto dosyasına işaret edip bir ağ adresine bağlanarak bir gRPC mikroservisini başlatır: ```typescript // main.ts import { NestFactory } from '@nestjs/core'; import { MicroserviceOptions, Transport } from '@nestjs/microservices'; import { join } from 'path'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.createMicroservice( AppModule, { transport: Transport.GRPC, options: { package: 'users', protoPath: join(__dirname, 'proto/users.proto'), url: '0.0.0.0:5000', }, }, ); await app.listen(); } bootstrap(); ``` Denetleyici, `@MessagePattern` yerine `@GrpcMethod` kullanır. Dekoratör, servis adını ve RPC yöntem adını argüman olarak alır ve doğrudan proto tanımıyla eşler: ```typescript // users.controller.ts import { Controller } from '@nestjs/common'; import { GrpcMethod } from '@nestjs/microservices'; import { UsersService } from './users.service'; @Controller() export class UsersController { constructor(private readonly usersService: UsersService) {} @GrpcMethod('UsersService', 'FindOne') async findOne(data: { id: string }) { return this.usersService.findById(data.id); } } ``` NestJS, proto yüklemeyi, serileştirmeyi ve HTTP/2 bağlantı yönetimini otomatik olarak halleder. Denetleyici yöntemi, düz TypeScript nesneleri alır — elle proto çözümlemesine gerek yoktur. ## NestJS'te gRPC Akış Desenleri Sunucu akışı, tek bir isteğin zamanla birden çok sonuç ürettiği senaryolara uyar — gerçek zamanlı fiyat akışları, sayfalı veritabanı imleçleri veya uzun süren bir görev sırasındaki ilerleme güncellemeleri gibi. İşleyici bir RxJS `Observable` döndürür ve NestJS, yayılan her değeri ayrı bir gRPC mesajı olarak istemciye akıtır: ```typescript // users.controller.ts — server streaming import { Observable, from } from 'rxjs'; import { map } from 'rxjs/operators'; import { GrpcMethod } from '@nestjs/microservices'; @GrpcMethod('UsersService', 'FindMany') findMany(data: { role: string; limit: number }): Observable { // Stream users matching the filter one by one const users$ = from(this.usersService.findByRole(data.role, data.limit)); return users$.pipe( map((user) => ({ id: user.id, email: user.email, name: user.name, role: user.role, })), ); } ``` Çift yönlü akış `@GrpcStreamCall()` kullanır. Hem istemci hem de sunucu bağımsız akışlar gönderir — sohbet sistemleri, ortak düzenleme veya çoğullanmış telemetri alımı için kullanışlıdır. İşleyici bir `grpc.ServerDuplexStream` örneği alır ve okuma/yazma döngüsünü elle yönetir. > **Akışta hata yönetimi** > > gRPC akışı içinde çöken bir Observable, tüm çağrıyı `CANCELLED` durumuyla sonlandırır. Akış mantığını `catchError` operatörleriyle sarmalayın ve gRPC'ye uygun hata meta verileri yayın. İşlenmeyen akış hataları, üretimdeki NestJS gRPC servislerinde gizemli bağlantı kopmalarının bir numaralı nedenidir. ## Hibrit Uygulamalar: Aynı Serviste HTTP ve gRPC Gerçek dünyadaki birçok NestJS servisi hem herkese açık bir REST API'sine hem de dahili gRPC uç noktalarına ihtiyaç duyar. [Hibrit uygulama deseni](https://docs.nestjs.com/faq/hybrid-application) birden çok taşımayı tek bir NestJS örneğine bağlar: ```typescript // main.ts — hybrid application import { NestFactory } from '@nestjs/core'; import { MicroserviceOptions, Transport } from '@nestjs/microservices'; import { join } from 'path'; import { AppModule } from './app.module'; async function bootstrap() { // HTTP server on port 3000 const app = await NestFactory.create(AppModule); // gRPC microservice on port 5000 app.connectMicroservice({ transport: Transport.GRPC, options: { package: 'users', protoPath: join(__dirname, 'proto/users.proto'), url: '0.0.0.0:5000', }, }); await app.startAllMicroservices(); await app.listen(3000); } bootstrap(); ``` Bu yaklaşım, tek bir sınırlandırılmış bağlam hem dış hem de dahili arayüzlere ihtiyaç duyduğunda ayrı servisler dağıtmaktan kaçınır. Aynı bağımlılık enjeksiyonu konteyneri, guard'lar, interceptor'lar ve pipe'lar her iki taşıma için de geçerlidir — bu da tekrarı azaltır ve davranışı tutarlı tutar. ## NestJS ile Servis Sınırları ve Alan Odaklı Tasarım Bir monoliti net sınırlar olmadan mikroservislere bölmek, dağıtık bir monolit yaratır — her iki mimarinin en kötü yanı. Her NestJS mikroservisi tek bir [sınırlandırılmış bağlama](https://martinfowler.com/bliki/BoundedContext.html) sahip olmalıdır: kendi veritabanı, kendi alan modelleri ve kendi dağıtım yaşam döngüsü. NestJS'te servis sınırlarını çizmek için pratik yönergeler: - **Her küme kökü (aggregate root) için bir NestJS modülü.** Eğer `Order` ve `OrderLine` her zaman birlikte değişiyorsa aynı servise aittir. Eğer `User` ve `Order` bağımsız olarak değişiyorsa ayrı servisleri hak eder. - **Alanlar arası yan etkiler için asenkron olaylar.** Bir sipariş verildiğinde, Kafka veya RabbitMQ üzerinden bir `order.created` olayı yayın. Envanter servisi tepki verir; sipariş servisinin onun varlığından haberi olmaz. - **Sözleşmeler için paylaşılan proto paketleri.** `.proto` dosyalarını paylaşılan bir depoda saklayın. Hem üretici hem de tüketici, türleri aynı doğruluk kaynağından üretir — sapma bir üretim olayı değil, bir CI hatası haline gelir. NestJS 11'in DI konteynerinden gelen mikroservis seçenekleri, servis yapılandırmasını test edilebilir kılar. Aracı URL'lerini `main.ts` içinde sabit kodlamak yerine bir `ConfigService` enjekte edin ve yeniden derleme olmadan ortam başına bağlantı dizelerini değiştirin. ## Güvenilirlik Desenleri: Zaman Aşımları, Yeniden Denemeler ve Devre Kesiciler Son teslim tarihleri (deadline) olmayan dahili gRPC çağrıları, tek bir yavaş bağımlılığı sistem genelinde bir kesintiye dönüştürür. Her `ClientProxy.send()` çağrısı bir zaman aşımı içermelidir: ```typescript // orders.service.ts import { Inject, Injectable } from '@nestjs/common'; import { ClientGrpc } from '@nestjs/microservices'; import { firstValueFrom, timeout, retry } from 'rxjs'; @Injectable() export class OrdersService { private usersService: any; constructor(@Inject('USERS_PACKAGE') private client: ClientGrpc) {} onModuleInit() { this.usersService = this.client.getService('UsersService'); } async getOrderWithUser(orderId: string, userId: string) { // 3-second deadline, 2 retries with exponential backoff const user = await firstValueFrom( this.usersService.findOne({ id: userId }).pipe( timeout(3000), retry({ count: 2, delay: (err, retryCount) => { const jitter = Math.random() * 100; return new Promise(r => setTimeout(r, 1000 * retryCount + jitter)); }}), ), ); return { orderId, user }; } } ``` Yeniden denemeler yalnızca idempotent işlemlere uygulanmalıdır. Bir `CreateOrder` çağrısını yeniden denemek, yinelenen siparişler riskini taşır. Bir `FindOne` sorgusunu yeniden denemek güvenlidir çünkü hiçbir yan etkisi yoktur. Devre kesici işlevselliği için [opossum](https://github.com/nodeshift/opossum) kütüphanesi NestJS ile iyi entegre olur. `ClientGrpc` çağrılarını, N ardışık hatadan sonra açılan ve yapılandırılabilir bir sıfırlama zaman aşımından sonra kapanan bir devre kesiciyle sarmalayın. > **NestJS 11 trace yayılımı** > > NestJS 11, trace ID'leri Kafka, RabbitMQ ve gRPC taşımaları arasında otomatik olarak yayar. [OpenTelemetry](https://opentelemetry.io/docs/languages/js/) ile birleştiğinde bu, özel interceptor'lar olmadan tam dağıtık izleme sağlar — manuel bağlam yayılımının gerekli olduğu NestJS 10'a göre önemli bir iyileştirme. ## NestJS Mikroservis Mülakat Soruları Arka uç pozisyonları için teknik mülakatlar, framework'e özgü desenlerin yanı sıra giderek artan ölçüde mikroservis bilgisini test ediyor. Aşağıdaki sorular, NestJS odaklı mülakatlarda en sık sorulan kavramları kapsar. **`@MessagePattern` ile `@EventPattern` arasındaki fark nedir?** `@MessagePattern` istek-yanıt uygular: istemci bir mesaj gönderir ve bir yanıt alana kadar bloke olur. `@EventPattern` gönder-unut (fire-and-forget) uygular: istemci bir olay yayar ve yürütmeye hemen devam eder. Arka planda `@MessagePattern` işleyicinin sonucunu taşıma üzerinden döndürürken, `@EventPattern` dönüş değerlerini atar. **NestJS, gRPC için `.proto` dosyalarını nasıl yükler ve bağlar?** NestJS, başlangıçta `.proto` dosyalarını ayrıştırmak ve servis tanımlayıcıları oluşturmak için `@grpc/proto-loader` paketini kullanır. `GrpcOptions` yapılandırması proto yolunu ve paket adını belirtir. `@GrpcMethod('ServiceName', 'MethodName')` ile işaretlenmiş denetleyiciler, ayrıştırılan tanımlayıcılarla eşleştirilir. Proto'da bildirilen bir yöntemin eşleşen bir işleyicisi yoksa NestJS bootstrap sırasında hata fırlatır. **gRPC, mikroservisler arasında REST'in yerini ne zaman almalı?** gRPC, tür güvenliği, performans ve akışın önemli olduğu dahili servisten servise çağrılara uyar. Protocol Buffers, JSON'dan daha küçük yükler ve daha hızlı serileştirme üretir. HTTP/2 çoğullaması bağlantı yükünü azaltır. REST, insan tarafından okunabilirliğin ve geniş araç desteğinin ham performanstan daha ağır bastığı herkese açık API'ler, tarayıcı istemcileri ve üçüncü taraf entegrasyonlar için tercih edilir olmaya devam eder. **Hibrit uygulama deseni nasıl çalışır?** `NestFactory.create()` bir HTTP sunucusu başlatır. `app.connectMicroservice()` çağrısı, aynı NestJS uygulama örneğine ek taşımalar — gRPC, Kafka, Redis veya desteklenen herhangi bir taşıyıcı — ekler. Tüm taşımalar aynı modül ağacını, DI konteynerini ve middleware ardışık düzenini paylaşır. `app.startAllMicroservices()` bağlı tüm taşıyıcıları başlatır ve `app.listen()` HTTP katmanını başlatır. **Hangi güvenilirlik desenleri kademeli arızaları önler?** En önemli üç desen: **zaman aşımları** (her RPC çağrısının bir son teslim tarihine ihtiyacı vardır), **jitter'lı yeniden denemeler** (yalnızca idempotent işlemler için, sürü etkisinden kaçınmak amacıyla üstel geri çekilme artı rastgele jitter ile) ve **devre kesiciler** (N hatadan sonra açık, soğuma süresinden sonra yarı açık, sağlık kontrolleri geçtiğinde kapalı). NestJS'in RxJS entegrasyonu, zaman aşımlarını ve yeniden denemeleri pipe operatörleri aracılığıyla bileştirilebilir kılar. NestJS mimari desenlerinde daha derin pratik için [NestJS modülleri ve bağımlılık enjeksiyonu](/technologies/node-nestjs/interview-questions/nestjs-modules-di) modülü, mikroservis kompozisyonunun temelini oluşturan DI esaslarını ele alır. [Middleware ve interceptor'lar](/technologies/node-nestjs/interview-questions/middleware-interceptors) modülü, taşımalar arasında paylaşılan kesişen kaygıları işler. ## Sonuç - NestJS 11'in taşıma soyutlaması, servislerin işleyici mantığını yeniden yazmadan TCP, gRPC, Kafka ve NATS arasında geçiş yapmasına olanak tanır — `@MessagePattern` ve `@EventPattern` dekoratörleri tüm taşımalarda aynı şekilde çalışır - Protocol Buffers'lı gRPC, `.proto` dosyaları aracılığıyla servisler arasında katı sözleşmeleri zorunlu kılar; entegrasyon hatalarını üretimde değil derleme zamanında yakalar - Hibrit uygulamalar HTTP ve gRPC'yi aynı NestJS örneğinde birleştirir; herkese açık ve dahili arayüzler için ayrı servisler dağıtma ihtiyacını ortadan kaldırır - RxJS Observable'ları aracılığıyla sunucu akışı, WebSocket karmaşıklığı olmadan gerçek zamanlı veri akışları sağlar — NestJS her Observable yayımını bir gRPC akış mesajına eşler - Her dahili RPC çağrısı bir son teslim tarihi gerektirir, yeniden denemeler yalnızca idempotent işlemlere uygulanır ve devre kesiciler tek bir yavaş servisin tam bir kesintiye kademeli olarak dönüşmesini önler - Servis sınırları alan odaklı tasarımı izler: servis başına bir sınırlandırılmış bağlam, alanlar arası iletişim için asenkron olaylar, sözleşme zorlaması için paylaşılan proto paketleri --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/tr/blog/node-nestjs/nestjs-microservices-grpc-architecture