API gateway adalah titik masuk tunggal untuk semua permintaan klien ke backend microservices Anda. Alih-alih klien mengetahui tentang sepuluh endpoint layanan yang berbeda, mereka berbicara ke satu gateway yang merutekan permintaan, menerapkan autentikasi, menerapkan batas laju, dan mengagregasi respons. Dalam arsitektur microservices NestJS, pola gateway sangat penting untuk menjaga batas layanan yang bersih sambil menyajikan API terpadu ke klien front-end.
API gateway berfungsi sebagai reverse proxy cerdas. Tanggung jawabnya: (1) Routing permintaan — mencocokkan jalur HTTP masuk ke microservice downstream yang sesuai; (2) Autentikasi dan otorisasi — memvalidasi JWT atau kunci API sebelum permintaan mencapai layanan; (3) Rate limiting — menerapkan kuota per klien atau per endpoint; (4) Transformasi permintaan/respons — mengadaptasi format payload antara kontrak klien dan layanan; (5) Circuit breaking — berhenti mengirim permintaan ke layanan yang gagal; (6) Agregasi respons — menggabungkan respons dari beberapa layanan menjadi satu payload untuk klien.
Di NestJS, gateway dapat berupa aplikasi khusus yang bertindak sebagai proxy HTTP. Gunakan @nestjs/axios untuk meneruskan permintaan ke layanan downstream, implementasikan Guards untuk autentikasi di tingkat gateway, dan gunakan Interceptors untuk rate limiting dan transformasi respons. Gateway berkomunikasi dengan layanan melalui gRPC atau HTTP.
API Gateway Architecture (NestJS)
┌────────────────────────────────────────────────────┐
│ Clients │
│ Browser │ Mobile App │ Partner API │ CLI │
└──────────────────┬─────────────────────────────────┘
│ HTTPS (REST / GraphQL)
▼
┌────────────────────────────────────────────────────┐
│ API Gateway (NestJS) │
│ │
│ [AuthGuard] → JWT validate → inject X-User-Id │
│ [RateLimitInterceptor] → Redis token bucket │
│ [TracingInterceptor] → inject X-Request-ID │
│ [CircuitBreakerInterceptor] → fail fast │
│ │
│ Route Table: │
│ /api/orders/* → OrderService (gRPC :50051) │
│ /api/invoices/* → InvoiceService (gRPC :50052) │
│ /api/reports/* → ReportService (HTTP :3003) │
└──────────┬────────────────┬───────────────────────┘
│ │
┌──────▼──────┐ ┌──────▼──────┐
│ Order │ │ Invoice │
│ Service │ │ Service │
│ (NestJS) │ │ (NestJS) │
└─────────────┘ └─────────────┘
BFF Extension: /api/dashboard → parallel calls to
UserService + OrderService + NotificationService → merged responseDari pengalaman membangun front-end untuk ERP Commsult: implementasikan request tracing di lapisan gateway dengan menyuntikkan header X-Request-ID ke setiap permintaan yang diteruskan. Log ID ini di gateway dan setiap layanan downstream. Saat men-debug masalah produksi, Anda dapat merekonstruksi perjalanan permintaan lengkap di seluruh layanan dengan mencari satu ID tersebut di log Anda.
Memusatkan autentikasi di gateway adalah salah satu manfaat terbesar dari pola ini. Alih-alih setiap microservice mengimplementasikan validasi JWT secara independen, gateway memvalidasi token dan meneruskan klaim yang didekode downstream sebagai header (X-User-Id, X-User-Roles). Layanan downstream mempercayai header ini tanpa memvalidasi ulang JWT — mereka hanya perlu memverifikasi permintaan berasal dari gateway (gunakan mTLS atau rahasia internal bersama).
// gateway-auth.guard.ts
@Injectable()
export class GatewayAuthGuard implements CanActivate {
constructor(private jwt: JwtService) {}
canActivate(ctx: ExecutionContext): boolean {
const req = ctx.switchToHttp().getRequest();
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) throw new UnauthorizedException();
const payload = this.jwt.verify(token);
// Downstream services trust these headers — never re-validate JWT
req.headers['x-user-id'] = payload.sub;
req.headers['x-user-roles'] = payload.roles.join(',');
req.headers['x-request-id'] = randomUUID(); // inject trace ID
return true;
}
}
// dashboard.controller.ts — BFF aggregation
@Controller('dashboard')
export class DashboardController {
@Get('overview')
async getOverview(@Headers('x-user-id') userId: string) {
// Parallel calls — total latency = max(latencies), not sum
const [profile, orders, notifications] = await Promise.all([
this.userService.getProfile(userId),
this.orderService.getRecent(userId, { limit: 5 }),
this.notificationService.getUnread(userId),
]);
return { profile, orders, notifications };
}
}Rate limiting melindungi layanan Anda dari penyalahgunaan dan memastikan penggunaan yang adil. Implementasikan rate limiting di gateway menggunakan algoritma token bucket atau sliding window yang didukung oleh Redis — sehingga batas dibagikan di beberapa instansi gateway. Di NestJS, paket @nestjs/throttler menangani ini dengan dukungan Redis melalui ThrottlerStorageRedisService.
Memusatkan semua lalu lintas melalui gateway berarti itu harus menjadi komponen Anda yang paling andal. Gateway yang down membawa seluruh permukaan API Anda bersamanya. Jalankan beberapa instansi gateway di belakang load balancer. Implementasikan pemeriksaan kesehatan di gateway dan circuit breaker pada panggilan layanan downstream. Monitor latensi dan tingkat kesalahan gateway sebagai SLO utama Anda.
Untuk tim yang sudah berinvestasi di NestJS, membangun gateway di NestJS memberikan kontrol penuh dan menggunakan kembali pola yang ada. Tetapi produk gateway yang dibuat khusus seperti Kong, Traefik, atau AWS API Gateway menangani rate limiting, auth, routing, caching, dan analitik di luar kotak. Gunakan gateway yang dibuat khusus ketika: Anda berada di lingkungan polyglot; Anda membutuhkan fitur enterprise.
Pola Backend-for-Frontend (BFF) memperluas gateway dengan menambahkan agregasi respons — gateway memanggil beberapa layanan secara paralel dan menggabungkan hasilnya menjadi satu respons untuk klien. Misalnya, halaman dashboard yang membutuhkan profil pengguna, pesanan terbaru, dan jumlah notifikasi dapat mendapatkan ketiganya dalam satu panggilan API. Di NestJS, implementasikan ini dengan Promise.all() untuk panggilan layanan paralel.
Sebelum ditayangkan: implementasikan endpoint pemeriksaan kesehatan di semua layanan downstream dan konfigurasikan gateway untuk memeriksanya; atur batas timeout pada semua permintaan yang di-proxy; tambahkan circuit breaker dengan respons fallback yang ditentukan; aktifkan distributed tracing dengan propagasi request ID; deploy beberapa instansi gateway dan uji failover.