# Microservices dengan NestJS di 2026: Arsitektur, gRPC, dan Pertanyaan Wawancara > Panduan lengkap arsitektur microservices NestJS dengan gRPC: transport layer, Protocol Buffers, streaming patterns, dan pertanyaan wawancara untuk backend engineer di 2026. - Published: 2026-05-26 - Updated: 2026-05-26 - Author: SharpSkill - Tags: nestjs, microservices, grpc, nodejs, typescript - Reading time: 10 min --- Arsitektur microservices telah menjadi standar industri untuk membangun aplikasi skala enterprise yang dapat diskalakan secara independen. NestJS, sebagai framework Node.js yang progresif, menyediakan abstraksi yang sangat baik untuk mengimplementasikan pola-pola microservices dengan berbagai transport layer. Artikel ini membahas secara mendalam cara membangun microservices dengan NestJS di tahun 2026, mulai dari arsitektur transport layer, integrasi gRPC, hingga pertanyaan-pertanyaan wawancara yang sering diajukan. > **Mengapa gRPC Lebih Unggul untuk Komunikasi Antar-Service** > > gRPC menggunakan Protocol Buffers (protobuf) yang menghasilkan payload 5-10x lebih kecil dibandingkan JSON, serta mendukung streaming bidireksional yang tidak tersedia pada REST tradisional. Untuk komunikasi internal antar-microservices, gRPC menawarkan performa dan type-safety yang jauh lebih baik. ## Arsitektur Transport Layer NestJS Microservices NestJS menyediakan dua decorator utama untuk menangani pesan dalam arsitektur microservices: `@MessagePattern` dan `@EventPattern`. Pemahaman perbedaan fundamental antara keduanya sangat penting untuk merancang sistem yang tepat. `@MessagePattern` digunakan untuk komunikasi request-response, di mana pengirim pesan menunggu balasan dari penerima. Pola ini cocok untuk operasi yang memerlukan konfirmasi atau data hasil. Sebaliknya, `@EventPattern` mengimplementasikan pola fire-and-forget, di mana pengirim tidak menunggu respons dan melanjutkan eksekusi segera setelah pesan dikirim. ```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); } } ``` Pada NestJS 11, method `unwrap()` diperkenalkan untuk memberikan akses langsung ke objek respons native dari transport layer. Fitur ini memungkinkan developer mengakses metadata spesifik transport seperti headers gRPC atau properti pesan Kafka yang sebelumnya tidak dapat diakses melalui abstraksi NestJS standar. ## Konfigurasi gRPC sebagai Transport Microservice NestJS gRPC (gRPC Remote Procedure Call) adalah framework RPC modern yang dikembangkan oleh Google. Untuk mengintegrasikan gRPC dengan NestJS, langkah pertama adalah mendefinisikan kontrak service menggunakan Protocol Buffers. ```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; } ``` File proto di atas mendefinisikan service `UsersService` dengan dua method: `FindOne` untuk mengambil satu user berdasarkan ID, dan `FindMany` yang mengembalikan stream user berdasarkan filter. Protocol Buffers menyediakan serialisasi biner yang sangat efisien dan schema yang ketat untuk validasi data. Konfigurasi bootstrap untuk microservice gRPC dilakukan pada file entry point aplikasi: ```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(); ``` Implementasi controller untuk menangani request gRPC menggunakan decorator `@GrpcMethod`: ```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); } } ``` Decorator `@GrpcMethod` menerima dua parameter: nama service dan nama method yang didefinisikan dalam file proto. NestJS secara otomatis melakukan serialisasi dan deserialisasi data menggunakan protobuf. ## Pola Streaming gRPC dalam NestJS gRPC mendukung empat pola komunikasi: unary (satu request, satu response), server streaming (satu request, multiple response), client streaming (multiple request, satu response), dan bidirectional streaming (multiple request, multiple response). Server streaming sangat berguna untuk mengirim data dalam jumlah besar secara bertahap, mengurangi memory footprint dan meningkatkan time-to-first-byte. NestJS memanfaatkan RxJS Observable untuk mengimplementasikan pola ini secara elegan: ```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, })), ); } ``` Integrasi RxJS memungkinkan penggunaan operator-operator reaktif seperti `map`, `filter`, `catchError`, dan `retry` untuk memproses stream data dengan cara yang deklaratif dan composable. > **Penanganan Error pada Streaming gRPC** > > Error pada streaming gRPC memerlukan penanganan khusus. Gunakan operator `catchError` dari RxJS untuk menangkap exception dan mengembalikan gRPC status code yang sesuai. Tanpa penanganan yang tepat, koneksi stream dapat terputus tanpa informasi error yang bermakna kepada client. ## Aplikasi Hybrid: HTTP dan gRPC pada Service yang Sama Dalam banyak kasus, sebuah service perlu mengekspos endpoint HTTP untuk client eksternal (mobile app, web browser) sekaligus endpoint gRPC untuk komunikasi internal antar-microservices. NestJS menyediakan mekanisme hybrid application untuk skenario ini: ```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(); ``` Dengan konfigurasi ini, service dapat menerima request HTTP pada port 3000 dan request gRPC pada port 5000 secara bersamaan. Controller yang sama dapat memiliki method dengan decorator `@Get()`, `@Post()` untuk HTTP dan `@GrpcMethod()` untuk gRPC. ## Batasan Service dan Domain-Driven Design dengan NestJS Penerapan Domain-Driven Design (DDD) dalam arsitektur microservices membantu mendefinisikan batasan yang jelas antar-service. NestJS module system sangat mendukung implementasi bounded context dari DDD. Setiap microservice sebaiknya merepresentasikan satu bounded context dengan aggregate root yang jelas. Komunikasi antar-bounded context dilakukan melalui event atau command yang didefinisikan dalam shared contract (proto files atau DTO). Prinsip-prinsip penting dalam menentukan batasan service meliputi kohesi fungsional yang tinggi di dalam service, kopling yang rendah antar-service, kemampuan untuk deploy dan scale secara independen, serta kepemilikan data yang jelas oleh masing-masing service. NestJS module encapsulation memungkinkan pengorganisasian kode berdasarkan domain. Setiap module dapat mengekspor hanya service yang diperlukan oleh module lain, menjaga internal implementation detail tetap tersembunyi. ## Pola Keandalan: Timeout, Retry, dan Circuit Breaker Dalam sistem terdistribusi, kegagalan adalah hal yang tak terhindarkan. Implementasi pola-pola keandalan sangat penting untuk membangun sistem yang resilient. ```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 }; } } ``` Kode di atas mengimplementasikan timeout 3 detik dan mekanisme retry dengan exponential backoff. Penambahan jitter (variasi acak) mencegah thundering herd problem ketika banyak client melakukan retry secara bersamaan. Circuit breaker pattern dapat diimplementasikan menggunakan library seperti `opossum` atau `cockatiel`. Pola ini mencegah cascade failure dengan membuka sirkuit ketika tingkat kegagalan melebihi threshold tertentu, memberikan waktu bagi service yang bermasalah untuk pulih. > **Propagasi Trace pada NestJS 11** > > NestJS 11 memperkenalkan dukungan bawaan untuk trace context propagation yang kompatibel dengan OpenTelemetry. Fitur ini memungkinkan distributed tracing end-to-end tanpa konfigurasi tambahan, mempermudah debugging dan monitoring pada sistem microservices yang kompleks. ## Pertanyaan Wawancara NestJS Microservices Berikut adalah pertanyaan-pertanyaan yang sering diajukan dalam wawancara teknis terkait microservices dengan NestJS: **Pertanyaan 1: Apa perbedaan antara @MessagePattern dan @EventPattern dalam NestJS microservices?** `@MessagePattern` mengimplementasikan pola request-response di mana pengirim pesan menunggu balasan dari penerima sebelum melanjutkan eksekusi. Pola ini cocok untuk operasi yang memerlukan konfirmasi atau data hasil, seperti pembuatan order yang perlu mengembalikan ID order yang dibuat. Sebaliknya, `@EventPattern` mengimplementasikan pola fire-and-forget di mana pengirim tidak menunggu respons. Pola ini ideal untuk notifikasi atau event yang tidak memerlukan acknowledgment, seperti event order telah dikirim yang memicu update status di beberapa service. **Pertanyaan 2: Bagaimana cara mengimplementasikan server streaming dengan gRPC di NestJS?** Server streaming diimplementasikan dengan mengembalikan RxJS Observable dari method yang didekorasi dengan `@GrpcMethod`. NestJS secara otomatis mengkonversi emission dari Observable menjadi stream gRPC. Developer dapat menggunakan operator RxJS seperti `from()` untuk mengkonversi array atau Promise menjadi Observable, kemudian menggunakan `map()` untuk mentransformasi setiap item sebelum dikirim ke client. **Pertanyaan 3: Jelaskan konsep hybrid application dalam NestJS dan kapan sebaiknya digunakan.** Hybrid application adalah aplikasi NestJS yang menjalankan multiple transport layer secara bersamaan, misalnya HTTP dan gRPC. Pola ini berguna ketika service perlu melayani client eksternal melalui REST API sekaligus berkomunikasi dengan microservices internal melalui gRPC. Method `connectMicroservice()` digunakan untuk menambahkan transport layer tambahan, dan `startAllMicroservices()` memulai semua transport layer yang terhubung. **Pertanyaan 4: Bagaimana strategi penanganan kegagalan dalam komunikasi antar-microservices?** Strategi utama meliputi implementasi timeout untuk membatasi waktu tunggu respons, retry dengan exponential backoff untuk menangani kegagalan sementara, circuit breaker untuk mencegah cascade failure, dan fallback mechanism untuk menyediakan respons alternatif ketika service tidak tersedia. RxJS menyediakan operator seperti `timeout()`, `retry()`, dan `catchError()` yang dapat dikomposisikan untuk mengimplementasikan strategi-strategi ini secara deklaratif. **Pertanyaan 5: Apa keuntungan menggunakan Protocol Buffers dibandingkan JSON untuk komunikasi microservices?** Protocol Buffers menawarkan beberapa keuntungan signifikan. Pertama, ukuran payload 5-10x lebih kecil karena serialisasi biner yang efisien. Kedua, parsing protobuf hingga 100x lebih cepat dibandingkan JSON. Ketiga, schema yang ketat memastikan type-safety dan backward compatibility dengan mekanisme field numbering. Keempat, code generation otomatis untuk berbagai bahasa pemrograman mengurangi boilerplate dan potensi error. Kelima, dukungan native untuk streaming yang tidak tersedia pada JSON over HTTP. Untuk memperdalam pemahaman tentang NestJS, pelajari juga materi tentang [NestJS modules and dependency injection](/technologies/node-nestjs/interview-questions/nestjs-modules-di) serta [middleware and interceptors](/technologies/node-nestjs/interview-questions/middleware-interceptors). ## Kesimpulan Membangun microservices dengan NestJS dan gRPC memberikan fondasi yang solid untuk sistem terdistribusi modern. Poin-poin utama yang perlu diingat: - **Transport layer abstraction**: NestJS menyediakan abstraksi yang konsisten untuk berbagai transport layer, memudahkan perpindahan atau kombinasi transport tanpa mengubah business logic. - **gRPC superiority**: Untuk komunikasi internal antar-service, gRPC menawarkan performa dan type-safety yang jauh lebih baik dibandingkan REST, terutama dengan dukungan streaming untuk data dalam jumlah besar. - **Hybrid flexibility**: Kemampuan menjalankan HTTP dan gRPC secara bersamaan memberikan fleksibilitas untuk melayani berbagai jenis client dengan satu codebase. - **Reliability patterns**: Implementasi timeout, retry dengan exponential backoff, dan circuit breaker adalah keharusan untuk sistem produksi yang resilient. - **Domain boundaries**: Penerapan prinsip DDD membantu mendefinisikan batasan service yang tepat, mengurangi kompleksitas dan meningkatkan maintainability. - **RxJS integration**: Integrasi mendalam dengan RxJS memungkinkan penanganan stream dan error handling yang elegan dan composable. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/id/blog/node-nestjs/nestjs-microservices-grpc-architecture