Protobuf — шта је, бинарни формат података и принцип рада

Аутор: IT Sectr Објављено: 2026-03-08 Време читања: 8 мин

Protocol Buffers (Protobuf) — је бинарни формат серијализације структурираних података, који је развио Google за ефикасну размену информација између сервиса. Формат захтева претходно дефинисање шеме у .proto датотекама, из којих се генерише код за различите језике. Према службеној документацији Google-а, Protobuf обезбеђује величину поруке 3-10 пута мању од JSON. Protobuf се користи у gRPC, Google Maps и хиљадама унутрашњих сервиса.

Главно

  • Protobuf — бинарни формат Google-а за серијализацију са компактним представљањем података
  • .proto шеме — строго типизован опис структуре података са компилацијом у код
  • Перформансе — серијализација 3-10 пута бржа и компактнија од JSON
  • Уназад компатибилност — еволуција шема без кварења постојећих клијената
  • gRPC — главна транспортна технологија за Protobuf у микрослужбама

Шта су Protocol Buffers?

Protocol Buffers — је механизам серијализације структурираних података, који је развио Google, сличан JSON-у и XML-у, али са суштинском разликом: подаци су кодирани у бинарни формат. То значи да се порука Protobuf-а не може прочитати голим оком, али заузима знатно мање места и обрађује се брже од текстуалних аналога.

Protobuf је настао унутар Google-а за решавање проблема перформанси при размени података између сервиса. 2008. године технологија је постала отворени пројекат са подршком за многе језике: C++, Java, Python, Go, JavaScript, Kotlin, Swift, Dart и друге. Верзија proto3, објављена 2016. године, поједноставила је синтаксу и додала подршку за већи број језика.

Кључна разлика између Protobuf-а и JSON-а — потреба за дефинисањем шеме пре почетка размене података. Датотека шеме (.proto) описује структуру поруке: поља, типове и јединствене бројеве поља. Из ове шеме, компајлер protoc генерише класе у циљном језику за серијализацију и десеријализацију.

Protobuf екосистем

  • gRPC — високоперформансни RPC оквир, који подразумевано користи Protobuf
  • protoc — компајлер .proto шема у код на различитим програмским језицима
  • Google API — већина Google-ових јавних API-ја користи Protobuf
  • Envoy Proxy — користи Protobuf за конфигурацију и размену података

Архитектура Protobuf-а

Архитектура Protobuf-а обухвата три кључне компоненте: језик дефиниције шеме (.proto), компајлер protoc и runtime библиотеке за конкретне језике. Програмер описује структуру података у .proto датотеци, покреће компилацију и добија готове класе за рад са овим подацима.

Свако поље у поруци Protobuf-а има јединствени број (field number) — то није редни број, већ tag који се у бинарном формату користи за идентификацију поља. Бројеви од 1 до 15 кодирају се једним бајтом, од 16 до 2047 — са два бајта. Због тога важна поља са високом фреквенцијом коришћења треба нумерисати од 1 до 15 ради оптимизације величине.

Типови података Protobuf-а

Protobuf подржава широк спектар типова: скаларне (int32, int64, float, double, bool, string, bytes), набрајања (enum), сложене (message) и специјалне (oneof, map). Сваки тип има одређену бинарну репрезентацију, оптимизовану за одговарајући сценарио коришћења.

Тип .proto C++ тип Java/Kotlin Опис
double double double 64-bit број с покретним зарезом
float float float 32-bit број с покретним зарезом
int32 int32 int 32-bit, variable-length encoding
int64 int64 long 64-bit, variable-length encoding
string string String UTF-8 стринг
bytes string ByteString Произвољни бајтови
bool bool boolean true / false

Предности бинарног формата

Protobuf даје три кључне предности у поређењу са текстуалним форматима: величину поруке, брзину серијализације и строго типовање. У високо оптерећеним системима и мобилним апликацијама са ограниченим саобраћајем, ове предности постају критичне.

Бинарна репрезентација Protobuf-а користи variable-length encoding (Varint) за бројеве: мали бројеви заузимају 1 бајт, велики — до 10 бајтова. Ово омогућава ефикасно кодирање идентификатора, заставица и бројача, који би у JSON или XML заузели десетине бајтова као текстуални стрингови. На пример, број 150 у Protobuf-у заузима 2 бајта, у JSON-у 3 бајта (као текст „150"), у XML-у 3 бајта + ознаке.

Додатна предност је уназад компатибилност. Додавање новог поља у шему не квари старе клијенте: они једноставно игноришу непозната поља. Брисање поља захтева само резервисање његовог броја да би се избегле колизије у будућности.

Дефинисање .proto шеме

.proto шема описује структуру података на специјалном језику. Датотека почиње навођењем синтаксе (proto3), пакета и импорта зависности. Свака порука се дефинише кључном речи message са пољима, где свако поље има тип, име и јединствени број.

Правила добре шеме: бројеви поља од 1 до 15 за често коришћена поља, смислена имена, груписање повезаних поља у посебне message, коришћење oneof за поља која могу бити само једна од неколико варијанти.

protobuf
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;
}

Угнежђене поруке

Поруке могу бити угнежђене: поље profile типа Profile ће садржати податке корисника. Подршка за угнежђивање омогућава описивање сложених хијерархијских структура без понављања дефиниција.

protobuf
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;
}

Генерисање кода из .proto

Компајлер protoc претвара .proto датотеке у изворни код на циљном језику. За Kotlin/Java користи се параметар --java_out, за Swift --swift_out (преко Apple Swift Protobuf додатка), за Dart --dart_out. Генерисане класе садрже builder методе за конструисање порука и методе серијализације/десеријализације.

На Android-у се за рад са Protobuf-ом користи додатак com.google.protobuf верзије 0.9+ у Gradle-у. Након додавања додатка и навођења .proto датотека, компилација аутоматски генерише Kotlin класе спремне за коришћење у апликацији.

kotlin
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 {
    // Серијализација у бинарни формат
    val bytes = user.toByteArray()

    // Десеријализација из бинарног формата
    return User.parseFrom(bytes)
}

Примери коришћења Protobuf-а

Protobuf је посебно ефикасан у микросервисној архитектури и мобилним апликацијама. Размотримо типичан сценарио: мобилна апликација добија листу производа од сервера преко gRPC-а. Порука Protobuf-а садржи информације о производу, укључујући идентификатор, назив, цену и категорију. Бинарни формат смањује величину одговора 5-8 пута у поређењу са JSON-ом.

gRPC сервис на Kotlin-у

Пример gRPC сервиса са Protobuf-ом на серверској страни. Сервис декларише RPC метод GetProducts, који прима захтев са параметрима пагинације и враћа листу производа. Имплементација на Kotlin-у користи генерисане класе за рад са захтевима и одговорима.

kotlin
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()
    }
}

Подешавање Protobuf-а у Android пројекту

Подешавање Protobuf-а у Android пројекту се врши преко Gradle додатка com.google.protobuf. Додатак аутоматски покреће компајлер protoc при компилацији и генерише Kotlin класе из .proto датотека. За рад је потребно додати додатак у build.gradle нивоа пројекта и применити га у модулу апликације.

Након подешавања Gradle-а, .proto датотеке се смештају у директоријум src/main/proto. Компајлер protoc их обрађује при свакој компилацији, генеришући Kotlin класе које се могу користити у коду апликације. Важно је правилно навести верзију protobuf и protoc да би се избегли конфликти зависности са другим библиотекама пројекта.

За iOS пројекте, Protobuf се повезује преко CocoaPods или Swift Package Manager-а. Додатак Swift Protobuf аутоматски генерише Swift структуре у складу са протоколом Codable. У Dart пројектима за Flutter користи се пакет protobuf, а компилација се врши преко dart run protoc_plugin.

Често постављана питања

Која је разлика између Protobuf-а и JSON-а?

Protobuf — бинарни формат са обавезном шемом, 3-10 пута компактнији од JSON-а. JSON — текстуални, читљив за човека, не захтева шему. Protobuf се брже серијализује и десеријализује, али захтева компилацију .proto датотека. JSON је лакши за отклањање грешака и не захтева претходно подешавање.

Како инсталирати компајлер protoc?

Преузмите protoc са GitHub издања protobuf-а за вашу платформу. За macOS инсталирајте преко brew install protobuf. За Windows преузмите zip архиву и додајте protoc.exe у PATH. За Android/Kotlin користите Gradle додатак com.google.protobuf који аутоматски покреће компилацију при изградњи.

Шта је gRPC и како је повезан са Protobuf-ом?

gRPC — је високоперформансни RPC оквир од Google-а, који користи Protobuf као интерфејсни језик (IDL) и формат серијализације. gRPC дефинише сервисе и RPC методе у .proto датотекама, генерише клијентски и серверски код, подржава стримовање и бинарне протоколе.

Које језике подржава Protobuf?

Google званично подржава: C++, Java, Kotlin, Python, Go, Ruby, C#, PHP, JavaScript, Objective-C, Swift и Dart. Заједница је развила подршку за Rust, TypeScript, Scala, Lua и друге језике. За мобилни развој доступни су Kotlin/Java (Android) и Swift/Objective-C (iOS).

Како обезбедити уназад компатибилност шема?

Protobuf подржава уназад компатибилност кроз правила: не мењајте бројеве поља, не бришите поља (користите reserved), додајте нова поља са новим бројевима. Стари клијенти игноришу непозната поља, нови клијенти добијају подразумеване вредности за недостајућа стара поља.

Закључак

  • Protocol Buffers — бинарни формат серијализације од Google-а са обавезном шемом података
  • Величина поруке 3-10 пута мања од JSON-а захваљујући Varint кодирању
  • Брзина серијализације и десеријализације већа од текстуалних формата
  • .proto шеме обезбеђују строго типовање и генерисање кода за 12+ језика
  • Уназад компатибилност омогућава еволуцију API-ја без кварења клијената
  • gRPC користи Protobuf као стандардни формат за микросервисну комуникацију
  • Идеалан за високо оптерећене системе и мобилне апликације са ограниченим саобраћајем

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође