Di dunia pengembangan microservices modern, gRPC menjadi pilihan utama berkat performanya yang tinggi, format pesan yang kompak, dan dukungan polyglot yang mumpuni. Namun, serupa dengan REST, arsitektur layanan berbasis gRPC juga membutuhkan mekanisme middleware untuk menangani fitur seperti logging, authentication, validation, hingga rate limiting secara konsisten dan reusable.
Dalam ekosistem Golang, library grpc_middleware
hadir sebagai solusi utama untuk merangkai interceptor dalam bentuk rantai (chain interceptor). Artikel ini membedah konsep chain interceptor pada gRPC menggunakan grpc_middleware
, dilengkapi contoh kode, simulasi sederhana, serta penjelasan visual menggunakan diagram mermaid.
Apa Itu gRPC Interceptor?
Sebelum memahami chaining, mari singgung ulang: interceptor pada gRPC adalah “middleware” — kode yang dieksekusi sebelum/atau sesudah handler utama pada suatu RPC. Ada dua jenis interceptor:
- UnaryInterceptor: Untuk unary RPC (permintaan-respons tunggal)
- StreamInterceptor: Untuk streaming RPC (request/response bertipe stream)
Aplikasi nyata interceptor antara lain:
- Logging otomatis setiap RPC
- Validasi Header/Token
- Rate limiting
- Monitoring dan instrumentasi (Prometheus, OpenTracing)
Tantangan: Middleware Bertumpuk
Pada aplikasi skala besar, satu endpoint RPC bisa menjalankan banyak “middleware” berurutan. Menulis semuanya langsung di handler menjadi anti-pattern: sulit di-maintain dan di-reuse.
Di sini, grpc_middleware
menjadi game changer: menyediakan mekanisme chain yang elegan, mirip Express.js di Node.js.
Instalasi & Setup Awal
Pastikan Anda sudah memiliki modul berikut:
go get github.com/grpc-ecosystem/go-grpc-middleware
Paket ini menawarkan helper untuk chaining unary dan stream interceptor.
Contoh: Membangun Chain Interceptor
Mari kita bangun tiga interceptor sederhana:
- Logging Interceptor: Menampilkan method RPC yang dipanggil
- Auth Interceptor: Memeriksa key sederhana di metadata
- Validation Interceptor: Memastikan request tidak kosong
1. Contoh Interceptor
import (
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"fmt"
"errors"
)
// Logging Interceptor
func LoggingInterceptor(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (interface{}, error) {
fmt.Println("[LOG] gRPC called:", info.FullMethod)
return handler(ctx, req)
}
// Auth Interceptor
func AuthInterceptor(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (interface{}, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok || len(md["x-api-key"]) == 0 || md["x-api-key"][0] != "secret123" {
return nil, errors.New("unauthorized")
}
return handler(ctx, req)
}
// Validation Interceptor (dummy)
func ValidateInterceptor(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (interface{}, error) {
if req == nil {
return nil, errors.New("empty request")
}
return handler(ctx, req)
}
2. Chaining dengan grpc_middleware
Dengan grpc_middleware
, kita compose interceptor di atas menjadi satu rantai:
import "github.com/grpc-ecosystem/go-grpc-middleware"
// ... interceptor definitions ...
server := grpc.NewServer(
grpc_middleware.WithUnaryServerChain(
LoggingInterceptor,
AuthInterceptor,
ValidateInterceptor,
),
)
Diagram Alur: Unary Chain Interceptor
flowchart LR A[gRPC Client] --> |RPC call| B[LoggingInterceptor] B --> |pass| C[AuthInterceptor] C --> |pass| D[ValidateInterceptor] D --> |pass| E[Actual Handler] E --> |response| D D --> |return| C C --> |return| B B --> |return| A
Penjelasan:
- Setiap interceptor memiliki akses ke handler selanjutnya, membentuk rantai.
- Jika di satu titik error terjadi (misal Auth gagal), proses “dipotong” dan error dikembalikan ke client.
Simulasi: Urut-Urutan Eksekusi Interceptor
Misalkan kita punya service method SayHello
, yang menerima request kosong dan metadata x-api-key
.
1. Client Request BENAR
- Metadata:
x-api-key: secret123
- Request:
{}
(tidak nil)
Eksekusi:
- LoggingInterceptor: mencatat log
- AuthInterceptor: API Key benar
- ValidateInterceptor: request valid
- Handler: dieksekusi
2. Client Request API Key SALAH
- Metadata: none
- Request:
{}
Eksekusi:
- LoggingInterceptor: mencatat log
- AuthInterceptor: API Key invalid → STOP, return error unauthenticated
3. Client Request NIL
- Metadata:
x-api-key: secret123
- Request:
nil
Eksekusi:
- LoggingInterceptor: mencatat log
- AuthInterceptor: API Key valid
- ValidateInterceptor: request nil → STOP, return error
Simulasi Output
Skenario | Logging | Auth | Validation | Handler | Output |
---|---|---|---|---|---|
API key benar, req ok | Ya | Ya | Ya | Ya | Sukses (Hello resp.) |
API key SALAH | Ya | Error | - | - | Error unauthorized |
Request NIL | Ya | Ya | Error | - | Error empty request |
Keterangan:
- Panah berhenti di kolom error, handler tidak dipanggil.
- Middleware dapat memotong atau meneruskan eksekusi.
Keunggulan Chain Interceptor
Reusable
Setiap interceptor bisa digunakan lintas service tanpa copy-paste.Order Control
Urutan eksekusi jelas & mudah diatur (mirip middleware stack pada web framework).Composable
Mudah injeksi fitur baru (audit, tracing, circuit breaker, dll).Separation of Concern
Handler RPC tetap fokus pada business logic.
Chaining Stream Interceptor
Selain unary, grpc_middleware
mendukung stream dengan API identik:
server := grpc.NewServer(
grpc_middleware.WithStreamServerChain(
MyStreamLoggingInterceptor,
AuthStreamInterceptor,
),
)
Handler stream mengikuti signature berbeda, tapi prinsip chaining tetap sama.
Tips Best Practice
- Susun dari yang bersifat universal ke spesifik (contoh: logging → auth → custom)
- Interceptor harus idempotent dan tidak mengubah request sembarangan
- Error handling jelas, jangan “panic” dalam interceptor
- Gunakan context untuk passing value antar interceptor jika perlu
Kesimpulan
Dengan chain interceptor dari grpc_middleware
, aplikasi gRPC di Golang menjadi modular, scalable, dan maintainable. Seperti rangkaian filter, kita bisa mengontrol aliran request ke handler, baik untuk alasan keamanan, logging, maupun observasi metrik.
Berinvestasilah pada desain interceptor sejak awal—karena semakin berkembang layanan Anda, semakin penting layer middleware yang tersusun rapi. Selamat mencoba dan scale up gRPC Anda secara profesional!
Referensi:
- https://github.com/grpc-ecosystem/go-grpc-middleware
- https://grpc.io/docs/guides/auth/
- https://dev.to/mohammadne/golang-grpc-middleware-1c8i
Happy coding! 🚀
17 Membuat Query untuk Mengambil Data Sederhana
Artikel Terhangat
38 Otorisasi dengan Interceptor gRPC
07 Jul 2025
37 Otentikasi di Middleware gRPC
07 Jul 2025

38 Otorisasi dengan Interceptor gRPC
