71. Integrasi gRPC dengan REST Gateway (grpc-gateway)
Di era modern pengembangan API, dua arsitektur sering menjadi perdebatan panas: REST dan gRPC. REST (Representational State Transfer) sudah menjadi standar default frontend-backend komunikasi via HTTP, sedangkan gRPC (Google Remote Procedure Call) dikenal dengan performa, efisiensi, dan kemudahan untuk menghubungkan layanan antar server, terutama pada sistem berskala mikroservis.
Namun, di banyak organisasi, biasanya ada kebutuhan untuk menyediakan API publik berbasis REST dan komunikasi internal antar layanan yang lebih optimal menggunakan gRPC. Mentranslasi antara REST dan gRPC secara manual jelas tidak efisien dan menambah beban maintenance codebase. Di sinilah grpc-gateway hadir sebagai solusi otomatis.
Pada artikel ini, saya akan membahas integrasi gRPC dengan REST Gateway memakai grpc-gateway, lengkap dengan contoh kode, diagram alur, hingga simulasi request-response. Mari kita mulai dari teori hingga penerapannya!
Kenapa Perlu Integrasi REST dan gRPC?
Sebelum masuk ke implementasi, mari pahami dulu alasan pentingnya integrasi ini:
| Kebutuhan | REST | gRPC |
|---|---|---|
| Kompatibilitas | Mendukung web & mobile | Terbatas di backend |
| Performance | Overhead JSON, HTTP/1.1 | Biner, HTTP/2, efisien |
| API Documentation | OpenAPI/Swagger | Protobuf schema |
| Streaming | Terbatas | Mendukung stream penuh |
| Evolusi API | Relatif mudah | Sangat mudah (Protobuf) |
Banyak tim ingin kedua keunggulan ini tanpa menulis dua implementasi terpisah. Dengan grpc-gateway, kita bisa menyediakan service yang sama melalui gRPC dan REST/JSON, serta menghasilkan dokumentasi OpenAPI secara otomatis.
Bagaimana grpc-gateway Bekerja?
Mari kita visualisasikan prosesnya dengan diagram berikut:
graph TD;
A[Client REST (HTTP/JSON)] -->|Request| B[grpc-gateway (Transcoder)];
B -->|gRPC call (Protobuf)| C[gRPC Server];
C -->|Response (Protobuf)| B;
B -->|Response (HTTP/JSON)| A;
Penjelasan:
- REST Client mengirim permintaan HTTP (biasanya JSON).
- grpc-gateway menerima, mentranslasi ke gRPC (Protobuf), dan meneruskan ke server gRPC asli.
- gRPC Server memproses permintaan dan mengirim response biner/Protobuf.
- grpc-gateway mentranslasi kembali ke JSON dan mengirim ke client REST.
Dengan pendekatan ini, Anda bisa menulis logika business one codebase, namun expose dua API berbeda (gRPC & RESTful) secara otomatis!
Instalasi dan Setup grpc-gateway
Kita akan gunakan Go (bahasa utama grpc-gateway), tapi konsepnya serupa di bahasa lain.
1. Install Protoc dan Plugin grpc-gateway
# Install protoc (compiler protobuf)
sudo apt install protobuf-compiler
# Install Go plugin untuk grpc, gateway, dan openapiv2
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest
# Pastikan $GOPATH/bin sudah di $PATH
export PATH="$PATH:$(go env GOPATH)/bin"
Contoh Implementasi: Simple User API
1. Definisikan Protobuf Service
File: user.proto
syntax = "proto3";
package user;
option go_package = "github.com/yourorg/yourrepo/gen/user;user";
import "google/api/annotations.proto";
service UserService {
rpc GetUser(GetUserRequest) returns (UserResponse) {
option (google.api.http) = {
get: "/v1/users/{id}"
};
}
}
message GetUserRequest {
string id = 1;
}
message UserResponse {
string id = 1;
string name = 2;
string email = 3;
}
Perhatikan annotation google.api.http: inilah kunci agar grpc-gateway tahu endpoint HTTP yang harus diskonversi ke RPC call.
2. Generate Code
protoc -I. \
-I $GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v2.*/third_party/googleapis \
--go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
--grpc-gateway_out=. --grpc-gateway_opt=paths=source_relative \
user.proto
3. Implementasi Server gRPC
File: server.go
package main
import (
"context"
"log"
"net"
"google.golang.org/grpc"
pb "github.com/yourorg/yourrepo/gen/user"
)
type server struct {
pb.UnimplementedUserServiceServer
}
func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.UserResponse, error) {
return &pb.UserResponse{
Id: req.Id,
Name: "Alice",
Email: "alice@example.com",
}, nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterUserServiceServer(s, &server{})
log.Println("gRPC server listening on :50051")
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
4. Implementasi REST Gateway
File: gateway.go
package main
import (
"context"
"log"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
pb "github.com/yourorg/yourrepo/gen/user"
)
func main() {
ctx := context.Background()
mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithInsecure()} // Insecure for dev
err := pb.RegisterUserServiceHandlerFromEndpoint(
ctx, mux, "localhost:50051", opts,
)
if err != nil {
log.Fatalf("Failed to register gateway: %v", err)
}
log.Println("REST gateway listening on :8080")
http.ListenAndServe(":8080", mux)
}
5. Simulasi Request: JSON ke gRPC Otomatis
Misalnya kita request:
curl http://localhost:8080/v1/users/1234
Response yang akan didapat:
{
"id": "1234",
"name": "Alice",
"email": "alice@example.com"
}
Proses dibalik layar:
- REST client (curl) request ke gateway
- Gateway translate ke gRPC request ke port 50051
- Server gRPC proses dan balas protobuf
- Gateway translate ke JSON response dan kembalikan ke client
Kelebihan dan Keterbatasan grpc-gateway
Kelebihan:
- Tidak perlu implementasi dua service berbeda (REST & gRPC).
- Mendukung path, query, request body sesuai OpenAPI.
- Bisa generate spesifikasi OpenAPI otomatis.
- Sangat efisien pada migrasi monolith ke mikroservis atau hybrid api.
Keterbatasan:
- Tidak semua fitur gRPC bisa di-expose via HTTP/JSON (misal bi-directional streaming belum 100% didukung).
- Tambah layer berarti potensi latency bertambah.
- Maintenansi mapping annotation di Protobuf.
Studi Kasus: Migrasi Bertahap ke gRPC
Salah satu pola migrasi yang sering digunakan:
- Langkah 1: Tulis ulang/migrasi business logic di service gRPC.
- Langkah 2: Sediakan gRPC API untuk komunikasi internal.
- Langkah 3: Expose REST/JSON untuk external consumer (frontend, mobile) via grpc-gateway.
- Langkah 4: Matikan REST API original setelah consumer migrasi ke baru.
Keuntungan pola ini – No breaking change di sisi client.
Kesimpulan
Mengintegrasikan gRPC dengan REST Gateway (grpc-gateway) merupakan solusi jembatan antara dunia lama REST dan dunia baru gRPC. Pendekatan ini sangat ideal untuk organisasi yang ingin modernisasi API tanpa mengorbankan compatibility maupun produktivitas developer.
Sebagai engineer, memanfaatkan alat seperti grpc-gateway bukan hanya soal efisiensi – ini juga tentang menurunkan technical debt dan memberikan seamless developer experience untuk tim lintas teknologi.
Jangan ragu eksplorasi grpc-gateway lebih lanjut, misal dengan authentication, custom error handling, atau generate documentasi OpenAPI secara otomatis. Happy coding, salam refactor!
Referensi: