tutorial

  1. Studi Kasus: Membuat gRPC Server di Go dan Client di Node.js

102. Studi Kasus: Membuat gRPC Server di Go dan Client di Node.js

Hari-hari ini, arsitektur layanan mikro (microservices) kian populer digunakan untuk membangun aplikasi berskala besar. Salah satu cara efektif berkomunikasi antar layanan adalah menggunakan protokol gRPC. gRPC memungkinkan pertukaran data yang cepat, efisien, serta memberikan pengalaman development yang solid melalui penggunaan Protobuf (Protocol Buffer) sebagai definisi kontraknya.

Dalam artikel ini, saya akan berbagi studi kasus bagaimana membangun gRPC server menggunakan bahasa Go dan mengkonsumsinya dengan client sederhana di Node.js. Proyek ini cocok buat kamu yang ingin melihat praktik interoperability lintas bahasa dengan gRPC, serta ingin memahami workflow full-stack-nya secara komprehensif.


Apa yang akan kita bangun?

Bayangkan kita akan membuat microservice sederhana bernama UserService. Service ini hanya punya satu endpoint: GetUser, yang jadi RPC-method untuk mengambil profile user berdasarkan user ID.

Berikut arsitektur jaringan sederhananya:

flowchart TD
    Client(Node.js) -->|gRPC call| GoServer(UserService)
    GoServer(UserService) -->|Response| Client(Node.js)

1. Menyiapkan Protokol Kontrak (user.proto)

Pertama, kita definisikan kontrak API dengan sebuah file Protobuf bernama user.proto:

syntax = "proto3";

package user;

service UserService {
    rpc GetUser (GetUserRequest) returns (GetUserResponse);
}

message GetUserRequest {
    string id = 1;
}

message GetUserResponse {
    string id = 1;
    string name = 2;
    string email = 3;
}

Simpan file ini di folder proto projectmu.

Best Practice: Selalu gunakan Protobuf untuk interoperabilitas bahasa dan backward compatibility pada perubahan skema data.


2. Membuat gRPC Server di Go

2.1. Meng-generate Stubs dari .proto

Install dulu dependencies di Go (modul utama: google.golang.org/grpc, dan plugin protoc-gen-go & protoc-gen-go-grpc):

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

Generate kode Go dari proto:

protoc --go_out=. --go-grpc_out=. proto/user.proto

Struktur project setelah generate akan seperti ini:

.
├── proto/
│   └── user.proto
├── user/
│   ├── user.pb.go
│   └── user_grpc.pb.go
└── main.go

2.2. Implementasi UserService di Go

File: main.go

package main

import (
    "context"
    "log"
    "net"

    pb "your-module-name/user" // import package hasil generate

    "google.golang.org/grpc"
)

type server struct {
    pb.UnimplementedUserServiceServer
}

func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
    // Simulasi: Ambil user by ID
    users := map[string]struct{ name, email string }{
        "1": {"Alice", "alice@mail.com"},
        "2": {"Bob", "bob@mail.com"},
    }
    user, found := users[req.Id]
    if !found {
        return nil, grpc.Errorf(404, "User not found")
    }

    return &pb.GetUserResponse{
        Id:    req.Id,
        Name:  user.name,
        Email: user.email,
    }, nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    grpcServer := grpc.NewServer()
    pb.RegisterUserServiceServer(grpcServer, &server{})
    log.Println("🚀 gRPC server running on :50051")
    if err := grpcServer.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

Penjelasan singkat:

  • Server Go di atas menjalankan satu RPC: GetUser.
  • Data disimulasikan lewat map.
  • Jalankan dengan go run main.go

3. Membuat gRPC Client Sederhana di Node.js

gRPC mendukung banyak bahasa, salah satunya JavaScript. Kita pakai package @grpc/grpc-js dan @grpc/proto-loader.

3.1. Install Dependencies

npm init -y
npm install @grpc/grpc-js @grpc/proto-loader

3.2. Implementasi Client

File: client.js

const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');

// Load proto file
const packageDefinition = protoLoader.loadSync('proto/user.proto', {
    keepCase: true,
    longs: String,
    enums: String,
    defaults: true,
    oneofs: true,
});
const userProto = grpc.loadPackageDefinition(packageDefinition).user;

// Create client
const client = new userProto.UserService('localhost:50051',
    grpc.credentials.createInsecure()
);

// Call GetUser
const userId = "1";
client.GetUser({ id: userId }, (error, response) => {
    if (error) {
        console.error('Error: ', error.message);
        return;
    }
    console.log('User Profile:', response);
});

Jalankan server Go, kemudian di terminal baru jalankan client Node.js dengan:

node client.js

Keluaran:

User Profile: { id: '1', name: 'Alice', email: 'alice@mail.com' }

4. Simulasi dan Tabel Perbandingan

Mari kita lihat simulasi komunikasi dan respons latency secara teoretis (jika dibandingkan dengan REST/JSON):

AspekgRPC (Protobuf)REST (JSON)
Parsing overheadRendahLebih tinggi
Payload sizeSangat padatLebih besar
KompatibilitasMulti-bahasaMulti-bahasa
Error handlingStatus via codeHTTP code
ToolingHarus ada protoSwagger/JSON
StreamingBuilt-inButuh custom

5. Alur Kerja gRPC pada Studi Kasus Ini

sequenceDiagram
    participant NodeClient as Client (Node.js)
    participant GoServer as Server (Go)
    NodeClient->>GoServer: GetUser(Request{ id: "1" })
    GoServer-->>NodeClient: GetUserResponse{ id: "1", name: "Alice", email: "alice@mail.com" }

6. Tips untuk Development Lintas Bahasa

  • Keep Your .proto in Sync
    Pastikan file Protobuf yang sama digunakan di semua bahasa. Gunakan submodule atau tools seperti buf.build.

  • Error Handling
    Injeksi error code via gRPC agar client lebih mudah melakukan troubleshooting.

  • Codegen Automation
    Gunakan Makefile, npm script, atau Taskfile agar regeneration code stubs otomatis saat ada perubahan schema.


Kesimpulan

Pada studi kasus ini, kita membuktikan gRPC sangat powerful untuk membangun distributed microservices lintas bahasa. Server dengan Go, client dengan Node.js — semua bicara dengan Protobuf sebagai bahasa bersama.

Selain lebih hemat bandwidth dan RAM, pipeline gRPC juga type-safe serta memudahkan proses scaling di masa depan. Next, kamu bisa mengembangkan fitur lain seperti autentikasi, interceptors, atau gunakan streaming untuk pipeline data real-time.

Enjoy ngoding, dan semoga artikel hands-on singkat ini bisa langsung kamu terapkan di project microservice-mu selanjutnya! 🚀


Referensi:


Tertarik eksplor lebih lanjut atau ada pertanyaan? Yuk diskusi di kolom komentar!

comments powered by Disqus