Menyatukan gerbang masuk sistem: peran API gateway untuk routing, rate limiting, dan autentikasi terpusat, serta gRPC sebagai protokol service-to-service yang efisien menggantikan HTTP/JSON

Saat sistem kalian tumbuh — apalagi setelah episode 12 memisahkan layanan — muncul kebutuhan baru: bagaimana mengatur semua pintu masuk? Di monolith, satu aplikasi menangani routing dan auth. Di sistem terdistribusi, ratusan endpoint tersebar di banyak service; memeriksa auth, rate limit, dan versioning di tiap service berarti duplikasi di mana-mana.
Solusinya dua lapis: API gateway sebagai pintu masuk terpusat untuk client, dan gRPC sebagai jalan raya antar service yang lebih efisien daripada HTTP/JSON. Episode ini membahas keduanya — kenapa dibutuhkan, kapan dipakai, dan bagaimana menyetelnya.
API gateway adalah satu titik masuk untuk semua client, yang meneruskan request ke service yang tepat. Ia mengambil alih tugas lintas-potong agar tidak diulang di tiap service.
| Tugas | Contoh |
|---|---|
| Routing | /v1/orders/* → order service |
| Autentikasi & otorisasi | Verifikasi token sebelum masuk service |
| Rate limiting | 100 req/menit per client (episode 20) |
| Aggregation | Gabungkan respons beberapa service |
| Observability | Satu titik logging, metrik, trace |
| Versioning | /v1, /v2 diarahkan beda service |
Keuntungan terbesarnya: kebijakan diubah satu tempat, tidak di tiap service. Menambah rate limit global cukup di gateway, bukan di 5 service.
Salah satu gateway populer adalah Kong — open source, plugin-based:
docker run -d --name kong-lab \
-e KONG_DATABASE=off \
-e KONG_PROXY_ACCESS_LOG=/dev/stdout \
-p 8000:8000 \
kong/kong-gateway:latestcurl -s -X POST http://localhost:8001/services \
-d "name=catalog" -d "url=http://catalog-svc:3000"
curl -s -X POST http://localhost:8001/services/catalog/routes \
-d "paths[]=/v1/products"Sekarang GET http://localhost:8000/v1/products diteruskan ke catalog service — dan kalian bisa menempelkan plugin auth/rate-limit ke route tersebut tanpa menyentuh kode service.
Note
Alternatif gateway yang juga populer: nginx sebagai reverse proxy sederhana, Traefik yang cloud-native, dan AWS API Gateway jika sudah di AWS. Untuk sistem kecil, nginx sering cukup; Kong/Traefik cocok untuk fitur plugin yang kaya.
Jangan pasang gateway karena terlihat modern. Untuk monolith atau modular monolith, gateway adalah lapisan ekstra tanpa manfaat — aplikasi sudah jadi pintu masuknya sendiri. Gateway mulai masuk akal saat:
HTTP/JSON untuk service-to-service memakai parsing text yang boros. Untuk percakapan antar service yang berulang dan intensif (ratusan ribu panggilan/detik), gRPC jauh lebih efisien:
.proto didukung tooling dan codegen di semua bahasa.syntax = "proto3";
package catalog;
service CatalogService {
rpc GetProduct(GetProductRequest) returns (Product);
rpc ListProducts(ListRequest) returns (ListResponse);
}
message GetProductRequest {
int64 id = 1;
}
message Product {
int64 id = 1;
string name = 2;
double price = 3;
int32 stock = 4;
}
message ListRequest {
int32 limit = 1;
}
message ListResponse {
repeated Product products = 1;
}import { createServer } from "connectrpc"
const server = createServer({
services: [CatalogService],
handlers: {
[CatalogService.method.getProduct]: async (req) => {
const { rows } = await db.query(
"SELECT * FROM products WHERE id = $1",
[req.id],
)
return { ...rows[0] }
},
},
})
server.listen(50051)import { createClient } from "connectrpc"
import { CatalogService } from "./gen/catalog_pb.js"
const client = createClient(CatalogService, baseUrl, {
transport: createConnectTransport({ baseUrl: "http://catalog:50051" }),
})
const product = await client.getProduct({ id: 42 })| Kriteria | HTTP/JSON (REST) | gRPC |
|---|---|---|
| Client | Browser, mobile, publik | Service internal |
| Format | Teks, mudah dibaca manusia | Biner, ringkas |
| Kecepatan | Sedang | Tinggi |
| Contract | OpenAPI (opsional) | .proto wajib |
| Streaming | SSE/WebSocket | Native bi-directional |
| Debug | Mudah (curl) | Butuh tool khusus (grpcurl) |
Aturan praktis: untuk API publik yang dipakai browser/mobile → REST/HTTP. Untuk percakapan antar service internal → gRPC. Tidak harus memilih satu — sistem sehat memakai keduanya: REST di tepi, gRPC di dalam.
Tip
Salah satu alasan kuat gRPC untuk internal: protobuf adalah kontrak yang ter-enforce — jika client dan server tidak cocok, compilasi gagal sebelum produksi. REST tanpa OpenAPI sering "cocok" sampai runtime, dan baru ketahuan saat integrasi (persis yang dicegah contract testing di episode 8).
Alur untuk sistem kita (macrolith, episode 12):
/v1/products → catalog, /v1/orders → order.upstream catalog_upstream { server catalog-svc:3000; }
upstream order_upstream { server order-svc:3001; }
server {
listen 80;
location /v1/products {
proxy_pass http://catalog_upstream;
}
location /v1/orders {
proxy_pass http://order_upstream;
}
}Semua request lewat gateway — jika mati, semua mati. Jalankan lebih dari satu instance di belakang load balancer (episode 21) dan pantau kesehatannya.
HTTP/JSON antar service dengan traffic tinggi boros bandwidth dan CPU. Ukur; jika internal traffic dominan, pindahkan ke gRPC.
Internal service yang bicara REST tanpa skema rawan rusak diam-diam. Jika memakai REST internal, setidaknya terapkan OpenAPI + contract test.
Auth dan rate limit di tiap service = tidak konsisten dan susah dirawat. Pindahkan ke gateway atau library bersama — pilih salah satu, jangan keduanya.
Episode 13 menyatukan gerbang sistem: API gateway untuk routing, auth, rate limit, dan observability terpusat; gRPC dengan protobuf untuk komunikasi internal yang efisien; plus aturan memakai REST di tepi dan gRPC di dalam.
Inti yang harus dibawa pulang:
Di episode 14 selanjutnya kita akan mengemas service menjadi artefak yang portable: container & dockerization — Dockerfile yang benar, optimasi image, dan docker-compose. Sampai jumpa di episode 14!