Pengenalan GRPC Part 1: Protobuf
Definisi umum
Mungkin sebagian dari kita pernah dengar istilah ‘grpc’, ‘protobuf’, dan sejenisnya. Apa sih itu gRPC dan gimana cara bikin servicenya?
gRPC (singkatan dari gRPC Remote Procedure Call) adalah sebuah protokol yang didevelop google tahun 2015. gRPC sendiri sekarang jadi opsi yang mulai populer dibanding REST karena performanya yang dinilai lebih oke. gRPC sendiri sudah banyak digunakan dalam internal service yang disediakan google. Salah satu contohnya adalah google pubsub.
Enough introduction! Mari mulai.
Pertama, dalam implementasi gRPC, kita perlu tahu apa itu protobuf. gRPC menggunakan protobuf untuk struktur data / kontrak. Misalkan seperti ini:
- REST API — JSON/XML
- gRPC — Protobuf
Singkatnya, protobuf adalah bahasa untuk mendefinisikan struktur data yang akan digunakan di gRPC. Mungkin kita lebih familiar dengan XML atau JSON. Nah protobuf itu juga mendefinisikan struktur/definisi dari sebuah struktur data. Contohnya adalah seperti berikut (diambil dari contoh di https://grpc.io/).
Contoh protobuf
syntax = "proto3";option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";package helloworld;// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
// Sends another greeting
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}// The request message containing the user's name.
message HelloRequest {
string name = 1;
}// The response message containing the greetings
message HelloReply {
string message = 1;
}
Mari kita breakdown:
syntax = "proto3";
Line ini menjelaskan kalo sintax protobuf yang kita pake adalah proto3. Line ini wajib kita specify dengan nilai “proto2” atau “proto3”. Perbedaan proto2 dan proto3 bisa dilihat di sini. TL;DR ada beberapa struktur dan translasi ke bahasa pemrograman yang berbeda dan breaking. Saya sendiri lebih sarankan pakai proto3 karena support yang lebih kuat baik dari segi developer maupun komunitas.
option java_multiple_files = true;
option
berguna untuk memberi informasi ke handler/translator dengan bagaimana protobuf seharusnya ditranslate. Selengkapnya mengenai apa yang bisa diconfig dengan option
bisa dibaca di [1]
package helloworld;
package
ini mirip dengan namespace di beberapa bahasa. Dengan package
, nantinya saat protobuf ditranslate ke bahasa lain, data dalam proto file kita akan mendapat prefix/namespace sesuai definisi package.
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
// Sends another greeting
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
service
berfungsi untuk mendefinisikan sekumpulan method/function yang akan diimplementasikan di RPC, beserta dengan list methodnya. Di sini kita bisa mengelompokkan method-method yang akan kita kelompokkan ke dalam service yang akan kita definisikan.
Sementara itu,rpc
adalah method yang akan kita sediakan, diikuti dengan nama method, input, dan outputnya. Input dan output sendiri wajib kita sediakan dalam definisi ini. Untuk membuat definisi method tanpa input atau output, kita bisa menggunakan “empty proto”[2]. Singkatnya, empty proto adalah message protobuf tanpa data yang sudah di-predefine oleh google, sebagai standar untuk menunjukkan method kita tidak butuh input atau output.
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
message
adalah struktur data inti yang kita definisikan di protobuf ini. Sintaksnya sendiri adalah keyword message
diikuti dengan nama struktur data beserta propertiesnya. Secara umum, struktur property adalah sebagai berikut:
[singular/repeated]
{required/optional}
tipe_data
nama_property
=
field_number
;
[singular/repeated]
mendefinisikan apakah property itu berupa single object atau collection/array. Di sini default valuenya adalah singular
.
{required/optional}
ini adalah fitur yang terdapat pada proto2
. Pada proto3
, semua property berupa optional dan kita tidak bisa membuat property tersebut menjadi required. Untuk lebih lengkapnya, lihat[3].
tipe_data
mendefinisikan tipe data untuk nama property itu. Tipe data ini mencakup beberapa primitive data type, seperti string
, int32
, int64
, float
, bool
, dll. Selain itu, kita juga bisa mendefinisikan tipe data yang lebih kompleks. Untuk spesifikasi tipe data lebih lengkap, lihat[4].
nama_property
mendefinisikan nama property kita.
field_number
digunakan sebagai identifier properti tersebut. field_number
dalam sebuah message
harus unik. Perhatikan bahwa field_number
akan memberikan ekstra byte untuk encoding. Angka 1–15 membutuhkan 1 byte. Angka 16–2047 membutuhkan 2 byte. Sehingga, gunakan field_number
yang rendah untuk message yang akan sering kita gunakan dalam message tersebut.
Akhir kata,
Demikian adalah struktur dasar dari protobuf. Untuk lebih lengkapnya, silakan baca[5], baik sebagai referensi maupun sebagai tambahan pengetahuan. Semoga bermanfaat!
Mari berdiskusi, sampaikan kritik, dan bagikan ke teman-teman!
Link:
[1] https://developers.google.com/protocol-buffers/docs/proto3#options
[2] https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/empty.proto
[4] https://developers.google.com/protocol-buffers/docs/overview#scalar
[5] https://developers.google.com/protocol-buffers/docs/overview