tutorial

  1. Studi Kasus: Mengelola Dependency Protobuf dengan Buf untuk Cross-platform


title: “109. Studi Kasus: Mengelola Dependency Protobuf dengan Buf untuk Cross-platform” published: true author: Senior Software Engineer tags:

  • protobuf
  • buf
  • cross-platform
  • dependency management
  • grpc

Dependency management untuk Protocol Buffers (protobuf) seringkali menjadi problem klasik dalam pengembangan sistem yang terdiri dari banyak layanan atau platform berbeda; entah itu microservices, frontend-backend, atau bahkan lintas bahasa seperti Go, Java, Python, dan JavaScript. Dalam artikel ini, saya akan membahas studi kasus mengelola dependensi Protobuf menggunakan Buf, sebuah tool modern yang semakin menjadi standar baru, sekaligus membagikan kontur masalah, solusi teknis, dan best practices yang bisa Anda terapkan jika berada di landscape serupa.


Latar Belakang Masalah

Mari kita mulai dengan gambaran umum yang cukup familiar:

  • Ada banyak repo (monorepo atau multi-repo) yang menggunakan file .proto untuk otorisasi API (gRPC, REST).
  • Setiap project dan tim ingin bebas memilih bahasanya: Go, Node.js, Python, Java, dst.
  • Copy-paste file proto menjadi rutinitas; versioning seringkali manual dan mudah missed.
  • Ingin clean code, otomatisasi, dan scaling bagus tanpa breaking changes.

Permasalahan mendasar:

  1. Stale dependencies: Custom-proto sering outdated antar repo.
  2. Conflicting version: Definisi proto ganda dengan versi berbeda.
  3. Difficulty in updating: Sulit update schema tanpa risk incompatibility.
  4. Multi-language generation: Kode stub dari proto harus digenerate untuk banyak bahasa, dependencies harus konsisten.

Mengapa Buf?

Buf adalah toolkit untuk linting, building, breaking change analysis, artifact generation, dan – yang sangat penting – dependency management serta module registry untuk Protobuf.

Benefit utama Buf:

  • Versi dan distribusi Protobuf schema dengan registry.
  • Dependency protopackage seperti npm untuk JavaScript.
  • Mudah untuk enforce rules dan linting.
  • Reproducible builds untuk banyak bahasa.

Studi Kasus: Multi-platform Payment System

Asumsikan kita punya sistem pembayaran seperti berikut:

  • Layanan payment (Go)
  • Layanan notification (Node.js)
  • Mobile apps (Flutter/Dart)
  • Web-frontend (React/TypeScript)

Semua mengonsumsi proto schema transaction.proto dan user.proto.


Permasalahan Klasik

Tanpa dependency management, biasanya workflow seperti ini:

┌──────────────────┐
│ payment-service  │
└───────┬──────────┘
        │
┌───────▼──────────┐
│  notification    │
└───────┬──────────┘
        │
┌───────▼───────────────┐
│ mobile & web clients  │
└───────────────────────┘

Setiap tim copy file .proto ke masing-masing repo mereka. Akhirnya, setiap repo bisa punya versi berbeda dari proto file, dengan perbedaan yg tidak terkontrol.


Solusi Arsitektur dengan Buf

Mari kita lihat diagram arsitektur dependency pengelolaan proto yang diatur oleh Buf:

flowchart TD
    subgraph Buf Registry
        A[transaction/v1] 
        B[user/v1]
    end
    subgraph Services & Client
        S1[payment-service (Go)]
        S2[notification (Node.js)]
        S3[mobile-app (Dart)]
        S4[web-app (TypeScript)]
    end
    S1-->|import@buf.build/org/transaction|A
    S2-->|import@buf.build/org/transaction|A
    S1-->|import@buf.build/org/user|B
    S3-->|import@buf.build/org/transaction|A
    S4-->|import@buf.build/org/transaction|A
    S2-->|import@buf.build/org/user|B
    S4-->|import@buf.build/org/user|B

Kini, semua layanan dan aplikasi klien menarik dependensi dari Buf Registry. Tak ada copy-paste, tak ada invisible divergence.


Implementasi Menggunakan Buf

1. Struktur Directory Protobuf Module

Misal, kita punya satu repo khusus schema proto:

proto/
  ├── buf.yaml
  ├── buf.lock
  └── transaction/
      └── v1/
          └── transaction.proto

transaction/v1/transaction.proto

syntax = "proto3";

package transaction.v1;

message Transaction {
    string id = 1;
    string user_id = 2;
    double amount = 3;
    string status = 4;
}

2. Konfigurasi Module di Buf

buf.yaml

version: v1
name: buf.build/yourorg/transaction
lint:
  use:
    - DEFAULT
breaking:
  use:
    - FILE

buf.lock akan otomatis digenerate.

3. Publikasi ke Buf Registry

Buf memiliki CLI command untuk publish module:

$ buf push

Sekarang, buf.build/yourorg/transaction dapat diimport dimanapun.


4. Konsumsi Proto via Buf di Layanan

Misal di dalam repo microservice Go payment:

buf.yaml

version: v1
deps:
  - buf.build/yourorg/transaction

Buf.lock generator seperti pada node_modules di NPM:
Lock dependencies agar version konsisten.


5. Generate Code untuk Bahasa Apapun

Dengan Buf, generation multi language lebih clean dibandingkan vanilla protobuf.

Contoh generate Go:

$ buf generate --template buf.gen.yaml

buf.gen.yaml

version: v1
plugins:
  - plugin: go
    out: gen/go
  - plugin: go-grpc
    out: gen/go

Untuk Node.js, Dart, atau TypeScript hanya perlu menambah plugin.


Simulasi Dependency Update

Misal ingin update schema Transaction menambah field created_at. Workflow update:

  1. Update transaction.proto
  2. Push ke Buf Registry (buf push)
  3. Update dependencies masing-masing service (buf mod update)
  4. Regenerate code stubs (buf generate)

Semua consumers menarik versi terbaru dengan buf mod update.


Tabel Perbandingan: Buf vs Manual Copy

FiturManual CopyBuf Registry
VersioningManualOtomatis
Dependency LockTidak adaAda (buf.lock)
Lint & Breaking CheckManualBuilt-in
Multi-language GeneratorRumitSederhana
Up-to-date DependenciesSering SalahKonsisten
CI/CD IntegrationRumitMudah

Best Practice & Lessons Learned

  • One source of truth: Hanya ada satu repo Protobuf yang dipublish ke Buf Registry.
  • Avoid breaking changes: Buf breaking check sangat membantu untuk backward compatibility.
  • Automasi di CI/CD: Linting, checking, dan regeneration otomatis setiap commit proto.
  • Buf lock (buf.lock): Dependency yang di-pin dan reproducible.
  • Documented registry versioning: Setiap tim tahu dependensinya menarik pada versi dan semver tertentu.

Kesimpulan

Pengalaman mengelola dependency Protobuf cross-platform lebih mudah, scalable, dan minim error dengan Buf Module & Registry dibanding teknik copy-paste atau solusi custom versioning lain. Dengan infrastructure as code yang repeatable, engineering team dapat menghemat waktu, mengurangi human error, dan berkolaborasi lebih efektif lintas bahasa maupun platform.

Buf bukan sekadar linter, melainkan cara berpikir baru dalam manajemen schema dan dependency Protobuf—dan dari pengalaman saya, investasi awal di Buf akan menghemat banyak waktu debugging dan refactoring dalam jangka panjang.


Referensi

Jika Anda punya pengalaman unik dalam mengelola dependency Protobuf, share di komentar!

comments powered by Disqus