Skip to content
Santekno.com | Tech Tutorials and Trends
ID
📖 0%
21 Jun 2025 · 4 mnt baca ·Artikel 13 / 110
Go

13 Implementasi Unary RPC

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

Pada tahun-tahun belakangan ini, konsep Remote Procedure Call (RPC) kian populer dalam pengembangan backend services. Salah satu pattern yang paling sederhana tapi sering dipakai adalah Unary RPC, di mana klien mengirim satu permintaan dan server mengembalikan satu respons. Di artikel ini, saya akan membahas konsep Unary RPC dan bagaimana mengimplementasikannya menggunakan gRPC di lingkungan Go (Golang). Mari kita berangkat dari teori, praktik, dan best practice dunia nyata.


Apa itu Unary RPC?

Sebelum masuk ke kode, kita perlu memahami konsep dasarnya. Unary RPC adalah model komunikasi satu-ke-satu antara klien dan server:

  • Single request –> Single response

Ilustrasi komunikasinya sangat mirip seperti fungsi biasa di dalam bahasa pemrograman, namun fungsi tersebut berjalan di server lain.

Alur Komunikasi Unary RPC

MERMAID
sequenceDiagram
    participant Client
    participant Server
    Client->>Server: Request (Data)
    Server-->>Client: Response (Data)

Studi Kasus: Service Pengelolaan Buku

Agar lebih nyata, kita akan buat simulasi sistem pengelolaan buku yang sederhana. Klien akan mengirim permintaan untuk mendapatkan informasi buku berdasarkan IDnya, dan server merespons dengan detail buku tersebut.


Membuat Definisi Protobuf

Kunci utama RPC di gRPC adalah file .proto yang mendefinisikan kontrak antar service.

protobuf
 1// book.proto
 2syntax = "proto3";
 3
 4package bookservice;
 5
 6// Request
 7message GetBookRequest {
 8  string id = 1;
 9}
10
11// Response
12message Book {
13  string id = 1;
14  string title = 2;
15  string author = 3;
16  int32  year = 4;
17}
18
19// Service
20service BookService {
21  rpc GetBook (GetBookRequest) returns (Book);
22}

Setelah membuat file ini, generate kode stub dengan perintah berikut:

bash
1protoc --go_out=. --go-grpc_out=. book.proto

Implementasi Server Unary RPC

Mari kita implementasikan service handler di Golang.

Struktur Dummy Database

go
1// book_server.go
2var books = map[string]*bookservice.Book{
3    "1": &bookservice.Book{Id: "1", Title: "Go Programming", Author: "John Doe", Year: 2021},
4    "2": &bookservice.Book{Id: "2", Title: "Distributed Systems", Author: "Jane Roe", Year: 2020},
5}

Handler RPC - GetBook

go
 1type server struct {
 2  bookservice.UnimplementedBookServiceServer
 3}
 4
 5func (s *server) GetBook(
 6    ctx context.Context,
 7    req *bookservice.GetBookRequest,
 8) (*bookservice.Book, error) {
 9    book, ok := books[req.Id]
10    if !ok {
11        return nil, status.Error(codes.NotFound, "book not found")
12    }
13    return book, nil
14}

Main server

go
 1func main() {
 2    lis, err := net.Listen("tcp", ":50051")
 3    if err != nil {
 4        log.Fatalf("Failed to listen: %v", err)
 5    }
 6
 7    grpcServer := grpc.NewServer()
 8    bookservice.RegisterBookServiceServer(grpcServer, &server{})
 9
10    log.Println("Server running on port :50051")
11    if err := grpcServer.Serve(lis); err != nil {
12        log.Fatalf("Failed to serve: %v", err)
13    }
14}

Implementasi Client Unary RPC

Mari simulasi klien yang melakukan request ke server menggunakan ID buku tertentu.

go
 1func main() {
 2    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
 3    if err != nil {
 4        log.Fatalf("Failed to connect: %v", err)
 5    }
 6    defer conn.Close()
 7
 8    client := bookservice.NewBookServiceClient(conn)
 9    ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
10    defer cancel()
11
12    bookID := "1"
13    res, err := client.GetBook(ctx, &bookservice.GetBookRequest{Id: bookID})
14    if err != nil {
15        log.Fatalf("Error: %v", err)
16    }
17
18    fmt.Printf("Book: %+v\n", res)
19}

Simulasi: Request & Response

Mari kita lihat bagaimana komunikasi terjadi.

LangkahDariKeData
Mengirim permintaan bukuClientServer{id: "1"}
Mencari bukuServer (db)InternalLookup berdasarkan ID
Mengirim responsServerClient{id: "1", title: "Go Programming", ...}


Alur Komunikasi Unggulan

Dengan unary RPC, alurnya simpel. Berikut diagram alur request-nya:

MERMAID
flowchart TD
    A[Client Kirim Request] --> B{Server Terima}
    B -- Buku Ada --> C[Server Kirim Data Buku]
    B -- Buku Tidak Ada --> D[Server Kirim Error]
    C & D --> E[Client Terima Respons]

Design ini sangat efisien untuk operasi yang memang hanya membutuhkan satu data dengan satu request.


Perbandingan dengan RPC Lain

Agar lebih jelas, berikut tabel perbandingan model komunikasi di gRPC:

Tipe RPCDariKeFlow
UnaryClientServerSatu request, satu response
Server StreamingClientServerSatu request, stream response
Client StreamingClientServerStream request, satu response
Bidirectional StreamingClientServerStream request, stream response


Manfaat dan Best Practice Unary RPC

Kelebihan

  • Sederhana – Mirip pemakaian fungsi biasa.
  • Cepat – Overhead sedikit, tidak ada stream.
  • Cocok untuk operasi CRUD simple, auth, lookup data, dsb.

Best Practice

  1. Validasi Data — Validasi permintaan di server sebelum proses data.
  2. Timeout — Gunakan context timeout di client untuk menghindari hang.
  3. Error Handling — Kirim error message yang jelas dari server ke client.
  4. Versioning — Pertimbangkan versioning API sejak awal.

Kesimpulan

Unary RPC adalah pattern yang sangat powerful sekaligus sederhana untuk microservices. Di Go, dengan gRPC kita bisa mengimplementasikannya dengan sangat efisien dan maintainable. Pattern ini cocok untuk berbagai use case, terutama operasi pemanggilan remote yang satu-permintaan-satu-jawaban.

Selamat bereksperimen dengan unary RPC di service kamu! Jika kamu punya pertanyaan atau ingin berdiskusi lebih dalam, jangan ragu tinggalkan komentar di bawah.

Artikel Terkait

💬 Komentar