gRPC telah menjadi salah satu framework komunikasi antar layanan paling populer di era cloud-native. Berkat performanya yang tinggi dan dukungannya terhadap berbagai bahasa pemrograman, gRPC sering diadopsi di berbagai proyek skala besar. Salah satu fitur gRPC yang powerful namun sering dianggap sepele adalah metadata. Metadata adalah pasangan key-value yang bisa dikirim bersama setiap permintaan (request) atau respons (response) dalam RPC, mirip dengan HTTP headers, namun lebih terintegrasi di level protokol gRPC.
Pada artikel kali ini, kita akan mengupas tuntas bagaimana membaca metadata pada sisi server gRPC dengan menggunakan contoh implementasi pada bahasa Go (Golang). Kita juga akan melihat contoh dan simulasi praktek, tabel, serta diagram alur untuk memudahkan pemahaman.
Mengenal Metadata di gRPC
Sebelum masuk ke implementasi, mari pahami dulu konsep metadata pada gRPC. Metadata memungkinkan kita untuk menyampaikan informasi tambahan seperti authentication token, request id, custom context, dan sebagainya yang sifatnya tidak rigid terikat pada protokol data utama (protobuf message).
Pada HTTP/2 (yang menjadi transport utama di gRPC), metadata biasanya diterjemahkan menjadi header. Namun, di gRPC, client dan server memiliki API khusus untuk berinteraksi dengan metadata.
Secara umum, metadata terdiri dari key-value pair sebagai berikut:
Key | Value | Keterangan |
---|---|---|
authorization | Bearer xxxxx | Token otorisasi |
client-id | 12345 | ID unik client |
custom-data | some-information | Data custom sesuai kebutuhan |
Diagram Alur Membaca Metadata di Server gRPC
Pengolahan metadata pada sisi server gRPC dapat digambarkan seperti berikut:
flowchart TD A[Client] -- Kirim RPC + Metadata --> B[gRPC Server] B -- Interceptor/Handler Baca Metadata --> C[Business Logic] C -- Response + Metadata Opsional --> A
Pada alur di atas, ketika client mengirim request, metadata ikut terkirim. Server bisa membaca metadata tersebut baik di handler biasa maupun lewat interceptor untuk kebutuhan cross-cutting seperti otentikasi atau logging.
Struktur Metadata di Go
Di Go, package utama untuk berinteraksi dengan metadata adalah google.golang.org/grpc/metadata
.
Berikut fungsi-fungsi pentingnya:
- md, ok := metadata.FromIncomingContext(ctx)
Mendapatkan metadata yang dikirim client dari context. - metadata.Pairs(“key”, “value”)
Membuat metadata baru untuk outbound.
Membaca Metadata di Server Handler
Mari kita buat sebuah service sederhana yang dapat membaca metadata yang dikirimkan oleh client.
Definisi Service (Protobuf)
syntax = "proto3";
package hello;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
Implementasi Server di Go
Inti dari membaca metadata bisa dilakukan di dalam masing-masing RPC handler.
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
pb "path/to/your/proto"
)
type server struct {
pb.UnimplementedGreeterServer
}
func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) {
// Membaca metadata dari context
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
fmt.Println("Tidak ada metadata yang dikirim")
} else {
// Menampilkan seluruh metadata yang diterima
for k, v := range md {
fmt.Printf("Metadata %s: %v\n", k, v)
}
}
// Ambil nilai tertentu
clientIds := md.Get("client-id")
if len(clientIds) > 0 {
fmt.Println("Client ID:", clientIds[0])
}
return &pb.HelloResponse{
Message: fmt.Sprintf("Hello, %s!", req.Name),
}, nil
}
Pada contoh di atas, handler SayHello
membaca semua metadata yang dikirimkan oleh client beserta value-nya.
Simulasi: Menjalankan Server dan Mengirim Metadata
Mari simulasikan client yang mengirimkan metadata.
Contoh Client
import (
"context"
"log"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
pb "path/to/your/proto"
"time"
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("gagal terkoneksi: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)
md := metadata.New(map[string]string{
"client-id": "abc-123",
"custom-data": "example-info",
})
ctx := metadata.NewOutgoingContext(context.Background(), md)
resp, err := c.SayHello(ctx, &pb.HelloRequest{Name: "Budi"})
if err != nil {
log.Fatalf("Error saat request: %v", err)
}
log.Printf("Server reply: %s", resp.Message)
}
Output pada Server
Metadata client-id: [abc-123]
Metadata custom-data: [example-info]
Client ID: abc-123
Server berhasil menangkap metadata yang dikirim oleh client.
Penggunaan Interceptor untuk Metadata
Dalam skala besar, membaca metadata biasanya dilakukan pada interceptor—middleware yang dapat menjalankan logic di luar business core, seperti otentikasi atau audit logging.
Contoh Unary Interceptor di Go
func metadataInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
md, ok := metadata.FromIncomingContext(ctx)
if ok {
if tokens := md.Get("authorization"); len(tokens) > 0 {
fmt.Println("Auth token:", tokens[0])
}
}
// Melanjutkan ke handler utama
return handler(ctx, req)
}
// Saat setup server
grpc.NewServer(
grpc.UnaryInterceptor(metadataInterceptor),
)
Kapan menggunakan interceptor:
- Validasi token sesi di seluruh method gRPC
- Audit logging metadata
- Monitoring dan tracing
Tabel: Perbandingan Cara Membaca Metadata
Cara | Keunggulan | Kekurangan | Use Case |
---|---|---|---|
Di Handler | Jadi satu dengan business logic | Redundant jika multi-method | Use-case spesifik per-RPC |
Di Interceptor | DRY, sekali implementasi global | Tidak per-RPC custom | Otentikasi, logging semua RPC |
Kombinasi | Fleksibel, bisa pilih kebutuhan | Mungkin perlu koordinasi | Crosscut + per-RPC kustom data parsing |
Best Practices
- Prefix metadata custom dengan identifier unik untuk menghindari bentrok (misal:
x-myapp-userid
). - Hindari metadata untuk payload besar—gunakan untuk data kecil seperti token, trace-id, dsb.
- Case insensitive – Key metadata tidak case sensitive, tapi konvensi lower-case lebih baik.
- Gunakan Interceptor untuk Crosscutting, handler untuk kebutuhan per-method.
Kesimpulan
Membaca metadata di server gRPC bukan hanya sekadar membaca key-value dari context, tapi merupakan pondasi pengembangan layanan yang aman, maintainable, dan scalable. Dengan memahami cara kerja dan praktik terbaik penggunaan metadata, kita bisa membangun aplikasi yang lebih modular, mudah diektensi, sekaligus aman.
Jangan ragu untuk mengeksplorasi fitur metadata lebih dalam, misal untuk implementasi rate limiting, distributed tracing, atau sistem monitoring terintegrasi di ekosistem microservices Anda!
Referensi
Selamat bereksperimen dengan metadata gRPC, demi keamanan & observabilitas sistem yang lebih baik!
17 Menambahkan Metadata pada gRPC Request
Artikel Terhangat
18 Membaca Metadata di Server gRPC
06 Jun 2025
17 Menambahkan Metadata pada gRPC Request
06 Jun 2025
16 Penanganan Error di Server gRPC
06 Jun 2025
13 Implementasi Unary RPC
06 Jun 2025
12 Membuat Client gRPC Pertama Anda
06 Jun 2025
11 Membuat Server gRPC Pertama Anda
06 Jun 2025

18 Membaca Metadata di Server gRPC

17 Menambahkan Metadata pada gRPC Request

16 Penanganan Error di Server gRPC

13 Implementasi Unary RPC

12 Membuat Client gRPC Pertama Anda
