tutorial

44 Reuse Message dengan import

Dalam pengembangan sistem terdistribusi atau microservices, saling bertukar data antar layanan menjadi keharusan. Protokol seperti gRPC berbasis Protocol Buffers (protobuf) sangat populer karena serialization-nya yang cepat dan representasi skema yang eksplisit. Namun, semakin besar skema data yang dikelola, semakin krusial juga bagaimana skema tersebut diorganisasi dan di-reuse. Salah satu fitur andalan protobuf yang sering underrated adalah kemampuan import untuk me-reuse message antar file protobuf.

Artikel ini akan membahas konsep reuse message dengan import di Protobuf, penggunaannya, serta best practice dalam organisasi skema data. Saya juga akan melampirkan contoh-contoh kode, simulasi pemanfaatan dalam project riil, tabel perbandingan implementasi, hingga diagram alur dengan Mermaid untuk memperjelas proses reusability dengan import.


1. Masalah Umum: Duplikasi Skema yang Tidak Scalable

Bayangkan Anda memiliki dua tim berbeda: team Payments dan team User Management. Keduanya sama-sama memerlukan definisi message User, misalnya:

// payments.proto
message User {
  string id = 1;
  string email = 2;
}
// users.proto
message User {
  string id = 1;
  string email = 2;
}

Praktik di atas terlihat sederhana, namun semakin banyak service dan message yang didefinisikan, duplikasi akan menciptakan masalah:

  • Inconsistent schema: Field diubah di satu file, layanan lain tidak ikut update.
  • Code maintenance nightmare: Setiap update duplikasi, harus dilakukan di banyak file.
  • Deployments lebih riskan: Potensi error meningkat saat skema tidak sinkron.

Lantas, bagaimana solusinya? Di sinilah fitur import protobuf berperan.


2. Konsep Dasar: Reuse dengan import

Protocol Buffers mendukung import layaknya bahasa pemrograman modern. Anda cukup mendefinisikan message sekali, kemudian bisa di-reuse di berbagai file .proto lain.

Struktur Direktori:

proto/
  user.proto
  payment.proto
  order.proto

user.proto

syntax = "proto3";

package myapp.user;

message User {
  string id = 1;
  string email = 2;
}

payment.proto

syntax = "proto3";

package myapp.payment;

import "user.proto";

message Payment {
  string payment_id = 1;
  myapp.user.User user = 2; // reuse message dari user.proto
  double amount = 3;
}

Dengan ini, message User didefinisikan sekali, dan langsung bisa digunakan di mana saja hanya dengan import.


3. Simulasi Skenario Project: Layanan Multi-Service

Misalkan perusahaan Anda memiliki layanan sebagai berikut:

Nama ServiceFile ProtoMessage yang Direuse
User Serviceuser.protoUser
Payment Servicepayment.protoUser (dari user.proto)
Order Serviceorder.protoUser (dari user.proto)

Perhatian: Semua service harus disepakati package dan path protokol yang konsisten agar compiler protobuf (protoc) dapat resolve seluruh dependency.

Simulasi Proses Compile:

Tiap developer cukup menjalankan:

protoc --proto_path=proto/ --go_out=. payment.proto

protoc akan secara otomatis mencari dan meng-compile user.proto jika ditemukan pada directory path yang sama atau sudah dimasukkan ke dalam option --proto_path.


4. Diagram Alur: Bagaimana import Bekerja?

Mari visualisasikan alur reuse message ketika protoc bekerja.

graph LR
    A[service.proto] -->|"import "user.proto""| B[user.proto]
    B --> C[message User didefinisikan]
    A --> D[message Payment didefinisikan]
    D -->|menggunakan User| C
    A & B --> E[protoc compiler]
    E --> F[Generated code dalam masing-masing bahasa]

Penjelasan:

  • File payment.proto melakukan import ke user.proto.
  • Message User hanya didefinisikan satu kali di user.proto.
  • Message Payment menggunakan User (fully-qualified dengan nama myapp.user.User jika beda package).
  • protoc akan resolve dependency semua file.

5. Studi Kasus: Mengubah Skema User Secara Terpusat

Anggap field User perlu ditambahkan nama lengkap:

// user.proto
message User {
  string id = 1;
  string email = 2;
  string full_name = 3;
}

Tanpa perlu ubah file lain, seluruh layanan yang meng-import user.proto kini otomatis support field baru ini setelah re-compile!


6. Tabel: Perbandingan Tanpa vs Dengan import

AspekTanpa importDengan import
Konsistensi SkemaRawat manual tiap fileSemua inherit dari satu sumber
Update SkemaBerisiko tidak sinkronCukup ubah satu file proto
MaintenanceLebih sulitMudah dan scalable
IDE SupportSulit lint cross-fileBetter auto-completion
Dependency BuildManual/linkingOtomatis resolve dependency

7. Best Practice Organisasi Protobuf

Beberapa best practice yang dapat memaksimalkan penggunaan import:

  • Pisahkan skema tipe yang akan di-shared ke file tersendiri.
    • Contoh: Semua message User, Product, Address dalam file proto masing-masing.
  • Gunakan penamaan namespace/package yang clear dan ternormalisasi.
  • Dokumentasi skema antar layanan secara terpusat.
  • Gunakan versioning pada file proto (ex: user_v1.proto/user_v2.proto) saat breaking change.
  • Jaga agar dependency antar proto tidak melingkar (circular import).

8. Advanced: Reuse Enum, Service & Extend dengan import

import tidak hanya digunakan untuk message. Enums, services, bahkan extension fields juga dapat di-reuse:

// status.proto
enum Status {
  ACTIVE = 0;
  INACTIVE = 1;
}

// user.proto
import "status.proto";
message User {
  ...
  Status status = 4;
}

9. Kesimpulan

Fitur import di Protobuf adalah senjata utama untuk reuse skema yang scalable, maintainable, dan mengurangi duplikasi kode. Dengan mendesain struktur proto yang modular, menempatkan message reusable di satu lokasi, serta disiplin dalam update dan documentation, project besar pun tetap robust dan mudah dikelola.

Jika project Anda sudah mulai “bau” karena duplikasi message, sekarang saatnya refactor dan gunakan kekuatan import di Protobuf!


Apakah Anda sudah mulai menerapkan reuse message dengan import? Bagikan pengalaman Anda di kolom komentar! 🚀

comments powered by Disqus

Topik Terhangat

programming
221
tutorial
88
tips-and-trick
43
jaringan
28
hardware
11
linux
4
kubernetes
1