75. Studi Kasus: API Gateway untuk gRPC Service
Kebutuhan akan sistem yang scalable, maintainable, dan performa tinggi mendorong banyak perusahaan untuk mengadopsi pendekatan microservices. Salah satu teknologi komunikasi antar service yang populer adalah gRPC, terutama untuk interaksi internal yang mengutamakan efisiensi dan contract-first API. Namun, gRPC belum terlalu ramah bagi konsumsi publik atau oleh client tradisional, seperti web browser atau mobile app, yang terbiasa dengan protokol HTTP/JSON. Masalah lain yang sering dihadapi adalah mengontrol akses, otentikasi, transformasi data, monitoring, dan sebagainya di satu pintu (API Gateway). Pada studi kasus kali ini, kita akan membahas rancangan dan implementasi sederhana API Gateway untuk gRPC Service.
Problem Statement
Misalkan Anda membangun sistem core banking dengan beberapa microservices, salah satunya adalah AccountService berbasis gRPC. Client eksternal (seperti front-end web atau mobile) hanya bisa berkomunikasi via REST. Anda butuh sebuah API Gateway yang:
- Mengkonversi permintaan REST menjadi request gRPC.
- Menyediakan endpoint RESTful agar dapat dengan mudah diintegrasikan ke front-end/client publik.
- Melakukan authentication/authorization di gateway.
- Mudah di-scale dan di-monitor.
Diagram Alur Sistem
flowchart LR
A[Client (Web/Mobile)] -- HTTP/JSON --> B(API Gateway)
B -- gRPC --> C[gRPC AccountService]
C -- Response gRPC --> B
B -- HTTP/JSON --> A
Pendekatan: Skenario dan Tools
Untuk studi kasus ini, kita akan menggunakan:
- gRPC: Sebagai backend service utama.
- Envoy Proxy atau grpc-gateway: Sebagai API Gateway.
- Go: Bahasa untuk implementasi karena dukungan tool yang solid untuk gRPC dan grpc-gateway.
- JWT Auth: Untuk simulasi autentikasi.
Definisi Service: AccountService
Mari mulai dengan mendefinisikan contract (protobuf) untuk AccountService.
// account.proto
syntax = "proto3";
package account;
service AccountService {
rpc GetAccount(GetAccountRequest) returns (GetAccountResponse) {}
}
message GetAccountRequest {
string account_id = 1;
}
message GetAccountResponse {
string account_id = 1;
string name = 2;
double balance = 3;
}
Setelah menulis file account.proto, generate stub server (dan client) menggunakan plugin protoc.
1. Implementasi gRPC Service
Buat implementasi server sederhana menggunakan Go.
// account_server.go
package main
import (
"context"
pb "path/to/accountpb"
)
type server struct {
pb.UnimplementedAccountServiceServer
}
func (s *server) GetAccount(ctx context.Context, req *pb.GetAccountRequest) (*pb.GetAccountResponse, error) {
// Simulasi database lookup
if req.GetAccountId() == "123" {
return &pb.GetAccountResponse{
AccountId: "123",
Name: "Jane Doe",
Balance: 2500000.0,
}, nil
}
return nil, status.Error(codes.NotFound, "account not found")
}
2. Kenapa Tidak REST Langsung?
Pertanyaan umum: Kenapa tidak expose gRPC service ini langsung sebagai REST?
Jawabannya adalah: gRPC lebih efisien (binary, multiplexing), lebih mudah contract-first, dan mendukung streaming. Namun, tidak semua client bisa native gRPC. Maka, API Gateway adalah solusi jembatan yang clean.
3. API Gateway dengan grpc-gateway
gRPC-Gateway adalah proyek open-source yang meng-generate proxy “reverse-proxy” HTTP RESTful ke gRPC endpoints.
Tambahan pada Proto File
Tambahkan annotation HTTP di proto:
import "google/api/annotations.proto";
service AccountService {
rpc GetAccount(GetAccountRequest) returns (GetAccountResponse) {
option (google.api.http) = {
get: "/v1/accounts/{account_id}"
};
}
}
Menjalankan Gateway
- Jalankan gRPC server di port misal
:9090. - Jalankan grpc-gateway server di port misal
:8080yang akan meneruskan request ke gRPC server.
main.go:
package main
import (
"context"
"log"
"net/http"
gw "path/to/accountpb"
"google.golang.org/grpc"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
)
func main() {
grpcEndpoint := "localhost:9090"
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithInsecure()}
err := gw.RegisterAccountServiceHandlerFromEndpoint(ctx, mux, grpcEndpoint, opts)
if err != nil {
log.Fatalf("failed to start HTTP gateway: %v", err)
}
http.ListenAndServe(":8080", mux)
}
4. Simulasi Request
Bayangkan client mengirimkan permintaan HTTP GET /v1/accounts/123:
GET /v1/accounts/123
Authorization: Bearer <jwt_token>
API Gateway akan:
- Men-translate request HTTP ke gRPC
GetAccount. - Menambah atau memvalidasi authentikasi (di interceptors).
- Mengembalikan hasil format JSON ke client.
Response example:
{
"account_id": "123",
"name": "Jane Doe",
"balance": 2500000.0
}
5. Middleware: Auth & Logics di Gateway
Letakkan middleware secara sentral di API Gateway, supaya downstream service tetap simple.
// Middleware HTTP untuk validasi JWT
type AuthMiddleware struct {
Next http.Handler
}
func (am *AuthMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
if !ValidateJWT(auth) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
am.Next.ServeHTTP(w, r)
}
// Penambahan pada main.go
authHandler := &AuthMiddleware{Next: mux}
http.ListenAndServe(":8080", authHandler)
6. Penggunaan Envoy sebagai API Gateway Alternatif
Selain grpc-gateway (yang cocok untuk prototyping atau Go stack), Anda bisa menggunakan Envoy untuk production grade. Envoy dapat mengkonfigurasi HTTP->gRPC transcoding, mendaftarkan rate limit, JWT validation, dll.
# Config potongan Envoy untuk HTTP-GRPC transcoding
static_resources:
listeners:
- address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
route_config:
#...
http_filters:
- name: envoy.filters.http.grpc_json_transcoder
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder
proto_descriptor: "/etc/protos/account.pb"
services: ["account.AccountService"]
print_options:
add_whitespace: true
Tabel Perbandingan
Berikut ringkasan perbandingan API Gateway yang umum untuk gRPC service:
| Gateway | Bahasa | Keunggulan | Kekurangan | Fitur Advanced |
|---|---|---|---|---|
| grpc-gateway | Go | Simpel, native Go | Tidak mendukung TLS kompleks, Hanya Go | Logging, Auth (custom) |
| Envoy Proxy | C++ | Performant, production proven | Konfigurasi lebih rumit | Rate limit, JWT |
| Kong | Lua/Go | Plugin ekosistem luas | Resource lebih berat | Rate limit, Auth |
7. Scaling dan Monitoring
Untuk kapasitas produksi:
- Gateway bisa dibungkus di container, lalu di-scale horizontal via Kubernetes.
- gRPC service bisa tetap di scale tersendiri.
- Monitoring request masuk/keluar di gateway, audit log, metrik latensi dsb.
Kesimpulan
API Gateway untuk gRPC service memungkinkan kita:
- Menggunakan gRPC secara internal untuk kinerja dan maintainability.
- Menyediakan API REST untuk client eksternal tanpa perlu memodifikasi setiap microservice.
- Menerapkan authentication, logging, monitoring, dan business logic di satu pintu.
- Infrastructure-agnostic; bisa diganti Envoy atau implementasi lain sesuai kebutuhan.
Dengan pendekatan ini, developer dapat fokus pada core business logic di masing-masing service sementara security, observability, dan device compatibility tetap terjaga.
Kesimpulan
Studi kasus ini secara sederhana mencerminkan salah satu best-practice pattern pada modern backend architecture. Memanfaatkan API Gateway sebagai jembatan antara dunia RESTful dan gRPC, Anda dapat menjaga sistem tetap modular dan future-proof. Experiment dan eksplorasi dengan berbagai gateway, temukan trade off paling cocok untuk kebutuhan Anda. Semoga studi kasus ini memberi inspirasi desain arsitektur dan eksekusi proyek Anda berikutnya!