A Protocol Buffers (Protobuf) egy bináris szerializációs formátum strukturált adatokhoz, amelyet a Google fejlesztett ki a hatékony információcsere érdekében a szolgáltatások között. A formátum előzetes séma meghatározását igényli .proto fájlokban, amelyekből kód generálódik különböző nyelvekhez. A Google hivatalos dokumentációja szerint a Protobuf 3-10-szer kisebb üzenetméretet biztosít, mint a JSON. Protobuf a gRPC-ben, a Google Maps-ben és több ezer belső szolgáltatásban használatos.
Főbb pontok
A Protocol Buffers egy a Google által fejlesztett strukturált adatok szerializációs mechanizmusa, hasonló a JSON-hoz és XML-hez, de alapvető különbséggel: az adatok bináris formátumba vannak kódolva. Ez azt jelenti, hogy a Protobuf üzenet szabad szemmel nem olvasható, de lényegesen kevesebb helyet foglal és gyorsabban feldolgozható, mint a szöveges megfelelői.
A Protobuf a Google-on belül jött létre a szolgáltatások közötti adatcsere teljesítményproblémáinak megoldására. 2008-ban a technológia nyílt forráskódú projektté vált számos nyelv támogatásával: C++, Java, Python, Go, JavaScript, Kotlin, Swift, Dart és mások. A 2016-ban kiadott proto3 verzió egyszerűsítette a szintaxist és több nyelv támogatását adta hozzá.
A kulcsfontosságú különbség a Protobuf és a JSON között a séma meghatározásának szükségessége az adatcsere megkezdése előtt. A sémafájl (.proto) leírja az üzenet szerkezetét: mezőket, típusokat és egyedi mezőszámokat. Ebből a sémából a protoc fordító célnyelvi osztályokat generál szerializációhoz és deszerializációhoz.
A Protobuf architektúrája három kulcsfontosságú komponenst foglal magában: a séma definíciós nyelvet (.proto), a protoc fordítót és a futásidejű könyvtárakat adott nyelvekhez. A fejlesztő leírja az adatstruktúrát egy .proto fájlban, elindítja a fordítást, és kész osztályokat kap az adatokkal való munkához.
A Protobuf üzenet minden mezője egyedi számmal (field number) rendelkezik — ez nem sorszám, hanem egy címke, amelyet a bináris formátum használ a mező azonosítására. Az 1-től 15-ig terjedő számok egy bájttal, a 16-tól 2047-ig terjedők két bájttal vannak kódolva. Ezért a gyakran használt fontos mezőket a méret optimalizálása érdekében 1-től 15-ig érdemes számozni.
A Protobuf a típusok széles skáláját támogatja: skaláris (int32, int64, float, double, bool, string, bytes), felsorolás (enum), összetett (message) és speciális (oneof, map). Minden típusnak meghatározott bináris reprezentációja van, optimalizálva a megfelelő használati forgatókönyvhöz.
| .proto típus | C++ típus | Java/Kotlin | Leírás |
|---|---|---|---|
| double | double | double | 64-bit lebegőpontos szám |
| float | float | float | 32-bit lebegőpontos szám |
| int32 | int32 | int | 32-bit, variable-length encoding |
| int64 | int64 | long | 64-bit, variable-length encoding |
| string | string | String | UTF-8 sztring |
| bytes | string | ByteString | Tetszőleges bájtok |
| bool | bool | boolean | true / false |
A Protobuf három kulcsfontosságú előnyt nyújt a szöveges formátumokkal szemben: üzenetméret, szerializációs sebesség és szigorú típusosság. A nagy terhelésű rendszerekben és korlátozott forgalmú mobilalkalmazásokban ezek az előnyök kritikussá válnak.
A Protobuf bináris reprezentációja variable-length encoding-ot (Varint) használ a számokhoz: a kis számok 1 bájtot, a nagyok akár 10 bájtot foglalnak. Ez lehetővé teszi az azonosítók, jelzők és számlálók hatékony kódolását, amelyek a JSON-ban vagy XML-ben szöveges sztringként tíz bájtot foglalnának. Például a 150-es szám a Protobufban 2 bájtot, a JSON-ban 3 bájtot (szövegként „150"), az XML-ben 3 bájtot + címkéket foglal.
További előny a visszamenőleges kompatibilitás. Új mező hozzáadása a sémához nem töri meg a régi klienseket: egyszerűen figyelmen kívül hagyják az ismeretlen mezőket. Mező törlése csak a számának lefoglalását igényli a jövőbeli ütközések elkerülése érdekében.
A .proto séma egy speciális nyelven írja le az adatstruktúrát. A fájl a szintaxis (proto3), a csomag és a függőségek importálásának megadásával kezdődik. Minden üzenet a message kulcsszóval van definiálva mezőkkel, ahol minden mezőnek típusa, neve és egyedi száma van.
A jó séma szabályai: 1-től 15-ig terjedő mezőszámok a gyakran használt mezőkhöz, értelmes nevek, kapcsolódó mezők csoportosítása külön message-be, a oneof használata olyan mezőkhöz, amelyek csak több változat egyike lehet.
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;
}
Az üzenetek beágyazhatók: a profile típusú Profile mező a felhasználó adatait tartalmazza. A beágyazás támogatása lehetővé teszi összetett hierarchikus struktúrák leírását a definíciók megkettőzése nélkül.
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;
}
A protoc fordító a .proto fájlokat forráskóddá alakítja a célnyelven. A Kotlin/Java esetében a --java_out paramétert, a Swift esetében a --swift_out (az Apple Swift Protobuf bővítményen keresztül), a Dart esetében a --dart_out paramétert használjuk. A generált osztályok builder metódusokat tartalmaznak üzenetek felépítéséhez, valamint szerializációs/deszerializációs metódusokat.
Androidon a Protobuf-al való munkához a com.google.protobuf 0.9+ verziójú Gradle bővítményt használjuk. A bővítmény hozzáadása és a .proto fájlok megadása után a fordítás automatikusan generálja a Kotlin osztályokat, amelyek készen állnak a használatra az alkalmazásban.
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 {
// Szerializáció bináris formátumba
val bytes = user.toByteArray()
// Deszerializáció bináris formátumból
return User.parseFrom(bytes)
}
A Protobuf különösen hatékony a mikroszolgáltatás architektúrában és a mobilalkalmazásokban. Tekintsünk egy tipikus forgatókönyvet: egy mobilalkalmazás terméklistát kap a szervertől gRPC-n keresztül. A Protobuf üzenet termékinformációkat tartalmaz, beleértve az azonosítót, nevet, árat és kategóriát. A bináris formátum 5-8-szor csökkenti a válasz méretét a JSON-hoz képest.
Példa gRPC szolgáltatásra Protobuf-al a szerver oldalon. A szolgáltatás deklarálja a GetProducts RPC metódust, amely lapozási paraméterekkel ellátott kérést fogad és terméklistát ad vissza. A Kotlin implementáció a generált osztályokat használja a kérésekkel és válaszokkal való munkához.
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()
}
}
A Protobuf beállítása Android projektben a com.google.protobuf Gradle bővítményen keresztül történik. A bővítmény automatikusan elindítja a protoc fordítót a fordítás során és Kotlin osztályokat generál a .proto fájlokból. A működéshez a bővítményt hozzá kell adni a projekt szintű build.gradle-hez és alkalmazni kell az alkalmazás modulban.
A Gradle beállítása után a .proto fájlok az src/main/proto könyvtárba kerülnek. A protoc fordító minden fordításnál feldolgozza őket, Kotlin osztályokat generálva, amelyek használhatók az alkalmazás kódjában. Fontos a protobuf és protoc verziójának helyes megadása a projekt más könyvtáraival való függőségi konfliktusok elkerülése érdekében.
iOS projektekhez a Protobuf CocoaPods-on vagy Swift Package Manager-en keresztül csatlakoztatható. A Swift Protobuf bővítmény automatikusan a Codable protokollnak megfelelő Swift struktúrákat generál. Flutter Dart projektjeiben a protobuf csomagot használjuk, a fordítás a dart run protoc_plugin-en keresztül történik.
Gyakran Ismételt Kérdések
Protobuf — bináris formátum kötelező sémával, 3-10-szer kompaktabb, mint a JSON. JSON — szöveges, ember által olvasható, nem igényel sémát. A Protobuf gyorsabban szerializál és deszerializál, de a .proto fájlok fordítását igényli. A JSON könnyebben debugolható és nem igényel előzetes beállítást.
Töltse le a protoc-ot a protobuf GitHub kiadásából a platformjának megfelelően. macOS-hez telepítse a brew install protobuf paranccsal. Windows-hoz töltse le a zip archívumot és adja hozzá a protoc.exe-t a PATH-hoz. Android/Kotlin esetén használja a com.google.protobuf Gradle bővítményt, amely automatikusan elindítja a fordítást a build során.
gRPC egy nagy teljesítményű RPC keretrendszer a Google-tól, amely a Protobuf-ot használja interfész nyelvként (IDL) és szerializációs formátumként. A gRPC szolgáltatásokat és RPC metódusokat definiál .proto fájlokban, kliens és szerver kódot generál, támogatja a streamelést és a bináris protokollokat.
A Google hivatalosan támogatja: C++, Java, Kotlin, Python, Go, Ruby, C#, PHP, JavaScript, Objective-C, Swift és Dart. A közösség támogatást fejlesztett ki a Rust, TypeScript, Scala, Lua és más nyelvekhez. Mobil fejlesztéshez Kotlin/Java (Android) és Swift/Objective-C (iOS) áll rendelkezésre.
A Protobuf a visszamenőleges kompatibilitást szabályokon keresztül támogatja: ne változtassa meg a mezőszámokat, ne töröljön mezőket (használja a reserved-et), adjon hozzá új mezőket új számokkal. A régi kliensek figyelmen kívül hagyják az ismeretlen mezőket, az új kliensek alapértelmezett értékeket kapnak a hiányzó régi mezőkhöz.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is