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.

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.
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.
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.
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:
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<MicroserviceOptions>(
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:
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:
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<any> {
// 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.
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:
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<MicroserviceOptions>({
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.
Siap menguasai wawancara Node.js / NestJS Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
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.
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.
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
Siap menguasai wawancara Node.js / NestJS Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
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 serta middleware and interceptors.
Siap menguasai wawancara Node.js / NestJS Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
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.
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Tag
Bagikan
Artikel terkait

NestJS + Prisma: stack backend modern untuk Node.js
Panduan lengkap untuk membangun API backend modern dengan NestJS dan Prisma. Setup, model, service, transaksi, dan praktik terbaik dijelaskan.

NestJS: Membangun REST API Lengkap dari Nol
Panduan lengkap membangun REST API profesional dengan NestJS. Controller, Service, Module, validasi dengan class-validator, dan penanganan error dijelaskan secara praktis.

Wawancara NestJS: Guards, Interceptors, dan arsitektur modular
Pertanyaan umum dalam wawancara teknis NestJS tentang Guards, Interceptors, dan arsitektur modular dengan contoh kode TypeScript konkret dan penjelasan teknis.