Ang Protocol Buffers (Protobuf) ay isang binary format ng serialization para sa nakaayos na data, na binuo ng Google para sa mahusay na pagpapalitan ng impormasyon sa pagitan ng mga serbisyo. Ang format ay nangangailangan ng paunang pagtukoy ng schema sa mga .proto file, kung saan nabubuo ang code para sa iba't ibang wika. Ayon sa opisyal na dokumentasyon ng Google, tinitiyak ng Protobuf ang laki ng mensahe na 3-10 beses na mas maliit kaysa sa JSON. Protobuf ay ginagamit sa gRPC, Google Maps at libu-libong panloob na serbisyo.
Mga Pangunahing Punto
Protocol Buffers ay isang mekanismo ng serialization ng nakaayos na data na binuo ng Google, katulad ng JSON at XML, ngunit may pangunahing pagkakaiba: ang data ay naka-encode sa binary format. Nangangahulugan ito na ang mensahe ng Protobuf ay hindi mababasa ng mata, ngunit ito ay sumasakop ng mas kaunting espasyo at naproseso nang mas mabilis kaysa sa tekstuwal na mga katumbas.
Ang Protobuf ay nilikha sa loob ng Google upang malutas ang mga problema sa pagganap sa pagpapalitan ng data sa pagitan ng mga serbisyo. Noong 2008, ang teknolohiya ay naging isang open-source na proyekto na may suporta para sa maraming wika: C++, Java, Python, Go, JavaScript, Kotlin, Swift, Dart at iba pa. Ang bersyon na proto3, na inilabas noong 2016, ay pinasimple ang syntax at nagdagdag ng suporta para sa mas maraming wika.
Ang pangunahing pagkakaiba sa pagitan ng Protobuf at JSON ay ang pangangailangan na tukuyin ang schema bago simulan ang pagpapalitan ng data. Ang file ng schema (.proto) ay naglalarawan ng istruktura ng mensahe: mga field, uri, at natatanging numero ng field. Mula sa schema na ito, ang compiler na protoc ay bumubuo ng mga klase sa target na wika para sa serialization at deserialization.
Arkitektura ng Protobuf ay may kasamang tatlong pangunahing bahagi: wika ng pagtukoy ng schema (.proto), compiler na protoc, at runtime library para sa mga tiyak na wika. Inilalarawan ng developer ang istruktura ng data sa .proto file, pinapatakbo ang compilation, at nakakakuha ng mga handa nang klase para sa pagtatrabaho sa data na ito.
Ang bawat field sa mensahe ng Protobuf ay may natatanging numero (field number) — hindi ito ordinal na numero, kundi isang tag na ginagamit sa binary format upang makilala ang field. Ang mga numero 1 hanggang 15 ay naka-encode ng isang byte, ang mga numero 16 hanggang 2047 ay dalawang byte. Kaya ang mahahalagang field na may mataas na dalas ng paggamit ay dapat bilangin mula 1 hanggang 15 para sa pag-optimize ng laki.
Sinusuportahan ng Protobuf ang malawak na hanay ng mga uri: scalar (int32, int64, float, double, bool, string, bytes), enumeration (enum), composite (message), at espesyal (oneof, map). Bawat uri ay may tiyak na binary na representasyon, na na-optimize para sa kaukulang senaryo ng paggamit.
| Uri ng .proto | Uri ng C++ | Java/Kotlin | Paglalarawan |
|---|---|---|---|
| double | double | double | 64-bit na floating-point number |
| float | float | float | 32-bit na floating-point number |
| int32 | int32 | int | 32-bit, variable-length encoding |
| int64 | int64 | long | 64-bit, variable-length encoding |
| string | string | String | UTF-8 string |
| bytes | string | ByteString | Arbitrary bytes |
| bool | bool | boolean | true / false |
Protobuf ay nagbibigay ng tatlong pangunahing bentahe kumpara sa mga text format: laki ng mensahe, bilis ng serialization, at mahigpit na pag-type. Sa mga system na may mataas na karga at mobile application na may limitadong trapiko, ang mga bentahe na ito ay nagiging kritikal.
Ang binary representasyon ng Protobuf ay gumagamit ng variable-length encoding (Varint) para sa mga numero: ang maliliit na numero ay sumasakop ng 1 byte, ang malalaki ay hanggang 10 bytes. Ito ay nagpapahintulot ng mahusay na pag-encode ng mga identifier, flag, at counter na sa JSON o XML ay sasakop ng sampu-sampung byte bilang text string. Halimbawa, ang numerong 150 sa Protobuf ay sumasakop ng 2 bytes, sa JSON 3 bytes (bilang text “150”), sa XML 3 bytes + tag.
Ang karagdagang bentahe ay backward compatibility. Ang pagdaragdag ng bagong field sa schema ay hindi sumisira sa mga lumang kliyente: basta na lang nila binabalewala ang mga hindi kilalang field. Ang pagtanggal ng field ay nangangailangan lamang ng pagreserba ng numero nito upang maiwasan ang mga banggaan sa hinaharap.
Ang .proto schema ay naglalarawan ng istruktura ng data sa isang espesyal na wika. Ang file ay nagsisimula sa pagtukoy ng syntax (proto3), package, at pag-import ng mga dependency. Bawat mensahe ay tinutukoy ng keyword na message na may mga field, kung saan ang bawat field ay may uri, pangalan, at natatanging numero.
Mga patakaran ng mabuting schema: numero ng field 1 hanggang 15 para sa madalas gamiting field, makabuluhang pangalan, pagpapangkat ng mga kaugnay na field sa hiwalay na message, paggamit ng oneof para sa mga field na maaaring isa lamang sa ilang variant.
syntax = "proto3";
package mobileapp;
message User {
string user_id = 1;
string name = 2;
string email = 3;
int32 age = 4;
UserRole role = 5;
repeated string tags = 6;
map<string, string> metadata = 7;
}
enum UserRole {
USER_ROLE_UNSPECIFIED = 0;
USER_ROLE_USER = 1;
USER_ROLE_ADMIN = 2;
USER_ROLE_MODERATOR = 3;
}
Ang mga mensahe ay maaaring i-nest: ang field na profile na uri ng Profile ay maglalaman ng data ng user. Ang suporta para sa nesting ay nagpapahintulot sa paglalarawan ng mga kumplikadong hierarchical structure nang walang pagdodoble ng mga kahulugan.
syntax = "proto3";
package mobileapp;
message Order {
string order_id = 1;
repeated OrderItem items = 2;
double total_price = 3;
PaymentInfo payment = 4;
}
message OrderItem {
string product_id = 1;
string title = 2;
int32 quantity = 3;
double price = 4;
}
message PaymentInfo {
string method = 1;
string transaction_id = 2;
double amount = 3;
}
Ang protoc compiler ay nagko-convert ng .proto file sa source code sa target na wika. Para sa Kotlin/Java ginagamit ang parameter --java_out, para sa Swift --swift_out (sa pamamagitan ng Apple Swift Protobuf plugin), para sa Dart --dart_out. Ang mga nabuong klase ay naglalaman ng builder method para sa paggawa ng mensahe at mga method ng serialization/deserialization.
Sa Android, para sa pagtatrabaho sa Protobuf ginagamit ang plugin na com.google.protobuf bersyon 0.9+ sa Gradle. Pagkatapos idagdag ang plugin at tukuyin ang .proto file, ang compilation ay awtomatikong bumubuo ng mga Kotlin class na handa nang gamitin sa application.
import com.google.protobuf.kotlin.toByteString
import com.example.mobileapp.UserOuterClass.User
fun createUser(): User {
return User.newBuilder()
.setUserId("usr_001")
.setName("IT Sectr")
.setEmail("team@itsectr.com")
.setAge(5)
.setRole(UserOuterClass.UserRole.USER_ROLE_ADMIN)
.addTags("mobile")
.addTags("backend")
.build()
}
fun serializeAndDeserialize(user: User): User {
// Serialization sa binary format
val bytes = user.toByteArray()
// Deserialization mula sa binary format
return User.parseFrom(bytes)
}
Protobuf ay lalong epektibo sa microservice architecture at mobile application. Isaalang-alang natin ang isang tipikal na senaryo: isang mobile application ay tumatanggap ng listahan ng produkto mula sa server sa pamamagitan ng gRPC. Ang mensahe ng Protobuf ay naglalaman ng impormasyon ng produkto, kabilang ang identifier, pangalan, presyo, at kategorya. Binabawasan ng binary format ang laki ng tugon ng 5-8 beses kumpara sa JSON.
Halimbawa ng gRPC service na may Protobuf sa server side. Ang serbisyo ay nagdedeklara ng RPC method na GetProducts na tumatanggap ng kahilingan na may mga parameter ng pagination at nagbabalik ng listahan ng produkto. Ang implementasyon sa Kotlin ay gumagamit ng mga nabuong klase para sa pagtatrabaho sa mga kahilingan at tugon.
import com.example.mobileapp.ProductServiceGrpcKt
import com.example.mobileapp.ProductOuterClass.Product
import com.example.mobileapp.ProductOuterClass.GetProductsRequest
import com.example.mobileapp.ProductOuterClass.GetProductsResponse
class ProductService : ProductServiceGrpcKt.ProductServiceCoroutineImplBase() {
override suspend fun getProducts(
request: GetProductsRequest
): GetProductsResponse {
val products = fetchProductsFromDb(
page = request.page,
limit = request.limit
)
return GetProductsResponse.newBuilder()
.addAllProducts(products)
.setTotalCount(products.size)
.build()
}
}
Pag-set up ng Protobuf sa Android project ay ginagawa sa pamamagitan ng Gradle plugin na com.google.protobuf. Awtomatikong pinapatakbo ng plugin ang protoc compiler sa compilation at bumubuo ng mga Kotlin class mula sa .proto file. Para sa trabaho, kailangang idagdag ang plugin sa build.gradle sa antas ng proyekto at ilapat ito sa module ng application.
Pagkatapos i-configure ang Gradle, ang .proto file ay inilalagay sa direktoryo ng src/main/proto. Pinoproseso ng protoc compiler ang mga ito sa bawat compilation, na bumubuo ng mga Kotlin class na maaaring gamitin sa code ng application. Mahalaga na tama ang pagtukoy ng bersyon ng protobuf at protoc upang maiwasan ang mga conflict ng dependency sa ibang library ng proyekto.
Para sa iOS projects, ang Protobuf ay ikinokonekta sa pamamagitan ng CocoaPods o Swift Package Manager. Ang Swift Protobuf plugin ay awtomatikong bumubuo ng mga Swift structure na naaayon sa Codable protocol. Sa Dart projects para sa Flutter, ginagamit ang protobuf package, at ang compilation ay ginagawa sa pamamagitan ng dart run protoc_plugin.
Mga Madalas Itanong
Protobuf — binary format na may mandatoryong schema, 3-10 beses na mas compact kaysa JSON. JSON — tekstuwal, nababasa ng tao, hindi nangangailangan ng schema. Mas mabilis mag-serialize at mag-deserialize ang Protobuf, ngunit nangangailangan ng compilation ng .proto file. Ang JSON ay mas madali sa debugging at hindi nangangailangan ng paunang configuration.
I-download ang protoc mula sa GitHub release ng protobuf para sa iyong platform. Para sa macOS, i-install sa pamamagitan ng brew install protobuf. Para sa Windows, i-download ang zip archive at idagdag ang protoc.exe sa PATH. Para sa Android/Kotlin, gamitin ang Gradle plugin na com.google.protobuf na awtomatikong nagpapatakbo ng compilation sa build.
gRPC ay isang high-performance RPC framework mula sa Google na gumagamit ng Protobuf bilang interface language (IDL) at serialization format. Tinutukoy ng gRPC ang mga serbisyo at RPC method sa .proto file, bumubuo ng client at server code, sumusuporta sa streaming at binary protocols.
Opisyal na sinusuportahan ng Google: C++, Java, Kotlin, Python, Go, Ruby, C#, PHP, JavaScript, Objective-C, Swift at Dart. Ang komunidad ay bumuo ng suporta para sa Rust, TypeScript, Scala, Lua at iba pang wika. Para sa mobile development, available ang Kotlin/Java (Android) at Swift/Objective-C (iOS).
Protobuf ay sumusuporta sa backward compatibility sa pamamagitan ng mga patakaran: huwag baguhin ang numero ng field, huwag tanggalin ang field (gumamit ng reserved), magdagdag ng bagong field na may bagong numero. Binabalewala ng mga lumang kliyente ang hindi kilalang field, ang mga bagong kliyente ay tumatanggap ng default na halaga para sa nawawalang lumang field.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din