Protobuf — vad är det, binärt dataformat och funktionsprincip

Författare: IT Sectr Publicerad: 2026-03-08 Lästid: 8 min

Protocol Buffers (Protobuf) är ett binärt serialiseringsformat för strukturerad data, utvecklat av Google för effektiv informationsutbyte mellan tjänster. Formatet kräver fördefiniering av schema i .proto-filer, från vilka kod genereras för olika språk. Enligt Googles officiella dokumentation ger Protobuf meddelandestorlekar 3-10 gånger mindre än JSON. Protobuf används i gRPC, Google Maps och tusentals interna tjänster.

Huvudpunkter

  • Protobuf — binärt format från Google för serialisering med kompakt datarepresentation
  • .proto-scheman — strikt typad beskrivning av datastruktur med kompilering till kod
  • Prestanda — serialisering 3-10 gånger snabbare och mer kompakt än JSON
  • Bakåtkompatibilitet — evolution av scheman utan att befintliga klienter bryts
  • gRPC — primär transportteknik för Protobuf i mikrotjänster

Vad är Protocol Buffers?

Protocol Buffers är en mekanism för serialisering av strukturerad data utvecklad av Google, liknande JSON och XML men med en grundläggande skillnad: data kodas i binärt format. Detta innebär att ett Protobuf-meddelande inte kan läsas med blotta ögat, men det tar betydligt mindre plats och bearbetas snabbare än textbaserade motsvarigheter.

Protobuf skapades internt på Google för att lösa prestandaproblem vid datautbyte mellan tjänster. År 2008 blev tekniken ett öppen källkodsprojekt med stöd för många språk: C++, Java, Python, Go, JavaScript, Kotlin, Swift, Dart och andra. Version proto3, som släpptes 2016, förenklade syntaxen och lade till stöd för fler språk.

Den viktigaste skillnaden mellan Protobuf och JSON är behovet av att definiera ett schema innan datautbytet påbörjas. Schemfilen (.proto) beskriver meddelandets struktur: fält, typer och unika fältnummer. Från detta schema genererar kompilatorn protoc klasser på målspråket för serialisering och deserialisering.

Protobuf ekosystem

  • gRPC — högpresterande RPC-ramverk som som standard använder Protobuf
  • protoc — kompilator av .proto-scheman till kod i olika programmeringsspråk
  • Google API — de flesta offentliga Google API:er använder Protobuf
  • Envoy Proxy — använder Protobuf för konfiguration och datautbyte

Protobuf arkitektur

Protobuf arkitektur omfattar tre nyckelkomponenter: språket för schemadefinition (.proto), kompilatorn protoc och runtime-bibliotek för specifika språk. Utvecklaren beskriver datastrukturen i en .proto-fil, kör kompileringen och får färdiga klasser för att arbeta med dessa data.

Varje fält i ett Protobuf-meddelande har ett unikt nummer (field number) — det är inte ett ordningsnummer utan en tagg som används i binärt format för att identifiera fältet. Nummer 1 till 15 kodas med en byte, nummer 16 till 2047 med två byte. Därför bör viktiga fält med hög användningsfrekvens numreras 1 till 15 för att optimera storleken.

Protobuf datatyper

Protobuf stöder ett brett spektrum av typer: skalära (int32, int64, float, double, bool, string, bytes), uppräkningar (enum), sammansatta (message) och speciella (oneof, map). Varje typ har en specifik binär representation optimerad för respektive användningsscenario.

.proto-typ C++-typ Java/Kotlin Beskrivning
double double double 64-bit flyttal
float float float 32-bit flyttal
int32 int32 int 32-bit, variable-length encoding
int64 int64 long 64-bit, variable-length encoding
string string String UTF-8-sträng
bytes string ByteString Godtyckliga byte
bool bool boolean true / false

Fördelar med binärt format

Protobuf ger tre viktiga fördelar jämfört med textformat: meddelandestorlek, serialiseringshastighet och strikt typning. I högt belastade system och mobila applikationer med begränsad trafik blir dessa fördelar kritiska.

Protobufs binära representation använder variable-length encoding (Varint) för tal: små tal tar 1 byte, stora upp till 10 byte. Detta möjliggör effektiv kodning av identifierare, flaggor och räknare som i JSON eller XML skulle ta tiotals byte som textsträngar. Till exempel tar talet 150 i Protobuf 2 byte, i JSON 3 byte (som texten ”150”), i XML 3 byte + taggar.

En ytterligare fördel är bakåtkompatibilitet. Att lägga till ett nytt fält i ett schema bryter inte gamla klienter: de ignorerar helt enkelt okända fält. Borttagning av ett fält kräver endast reservering av dess nummer för att undvika kollisioner i framtiden.

Definiera .proto-schema

.proto-schema beskriver datastrukturen på ett speciellt språk. Filen börjar med att specificera syntaxen (proto3), paket och import av beroenden. Varje meddelande definieras med nyckelordet message med fält, där varje fält har en typ, ett namn och ett unikt nummer.

Regler för ett bra schema: fältnummer 1 till 15 för ofta använda fält, meningsfulla namn, gruppering av relaterade fält i separata message, användning av oneof för fält som bara kan vara ett av flera alternativ.

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

Nästlade meddelanden

Meddelanden kan vara nästlade: fältet profile av typen Profile kommer att innehålla användardata. Stöd för nästling gör det möjligt att beskriva komplexa hierarkiska strukturer utan att duplicera definitioner.

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

Generera kod från .proto

Kompilatorn protoc omvandlar .proto-filer till källkod på målspråket. För Kotlin/Java används parametern --java_out, för Swift --swift_out (via Apple Swift Protobuf-plugin), för Dart --dart_out. De genererade klasserna innehåller byggmetoder för att konstruera meddelanden och metoder för serialisering/deserialisering.

På Android används plugin-programmet com.google.protobuf version 0.9+ i Gradle för att arbeta med Protobuf. Efter att ha lagt till plugin-programmet och specificerat .proto-filer genererar kompileringen automatiskt Kotlin-klasser redo att användas i applikationen.

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 {
    // Serialisering till binärt format
    val bytes = user.toByteArray()

    // Deserialisering från binärt format
    return User.parseFrom(bytes)
}

Exempel på Protobuf-användning

Protobuf är särskilt effektivt i mikrotjänstarkitektur och mobila applikationer. Låt oss överväga ett typiskt scenario: en mobilapplikation tar emot en produktlista från servern via gRPC. Protobuf-meddelandet innehåller produktinformation, inklusive identifierare, namn, pris och kategori. Det binära formatet minskar svarsstorleken 5-8 gånger jämfört med JSON.

gRPC-tjänst i Kotlin

Exempel på gRPC-tjänst med Protobuf på serversidan. Tjänsten deklarerar RPC-metoden GetProducts som tar emot en begäran med pagineringsparametrar och returnerar en produktlista. Implementeringen i Kotlin använder de genererade klasserna för att arbeta med förfrågningar och svar.

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

Konfigurera Protobuf i Android-projekt

Konfigurering av Protobuf i ett Android-projekt görs via Gradle-plugin-programmet com.google.protobuf. Plugin-programmet startar automatiskt kompilatorn protoc under kompileringen och genererar Kotlin-klasser från .proto-filer. För att fungera måste plugin-programmet läggas till i build.gradle på projektnivå och tillämpas i applikationsmodulen.

Efter att ha konfigurerat Gradle placeras .proto-filer i katalogen src/main/proto. Kompilatorn protoc bearbetar dem vid varje kompilering och genererar Kotlin-klasser som kan användas i applikationskoden. Det är viktigt att ange rätt versioner av protobuf och protoc för att undvika beroendekonflikter med andra bibliotek i projektet.

För iOS-projekt ansluts Protobuf via CocoaPods eller Swift Package Manager. Swift Protobuf-plugin genererar automatiskt Swift-strukturer som överensstämmer med Codable-protokollet. I Dart-projekt för Flutter används paketet protobuf och kompilering sker via dart run protoc_plugin.

Vanliga frågor

Vad är skillnaden mellan Protobuf och JSON?

Protobuf — binärt format med obligatoriskt schema, 3-10 gånger mer kompakt än JSON. JSON — textbaserat, läsbart för människor, kräver inget schema. Protobuf serialiserar och deserialiserar snabbare men kräver kompilering av .proto-filer. JSON är lättare att felsöka och kräver ingen förkonfiguration.

Hur installerar man kompilatorn protoc?

Ladda ner protoc från GitHub-utgåvan av protobuf för din plattform. För macOS, installera via brew install protobuf. För Windows, ladda ner zip-arkivet och lägg till protoc.exe i PATH. För Android/Kotlin, använd Gradle-plugin-programmet com.google.protobuf som automatiskt startar kompileringen vid bygget.

Vad är gRPC och hur är det relaterat till Protobuf?

gRPC är ett högpresterande RPC-ramverk från Google som använder Protobuf som gränssnittsspråk (IDL) och serialiseringsformat. gRPC definierar tjänster och RPC-metoder i .proto-filer, genererar klient- och serverkod, stöder strömning och binära protokoll.

Vilka språk stöder Protobuf?

Google stöder officiellt: C++, Java, Kotlin, Python, Go, Ruby, C#, PHP, JavaScript, Objective-C, Swift och Dart. Communityn har utvecklat stöd för Rust, TypeScript, Scala, Lua och andra språk. För mobil utveckling finns Kotlin/Java (Android) och Swift/Objective-C (iOS).

Hur säkerställer man bakåtkompatibilitet för scheman?

Protobuf stöder bakåtkompatibilitet genom regler: ändra inte fältnummer, ta inte bort fält (använd reserved), lägg till nya fält med nya nummer. Gamla klienter ignorerar okända fält, nya klienter får standardvärden för saknade gamla fält.

Sammanfattning

  • Protocol Buffers — binärt serialiseringsformat från Google med obligatoriskt dataschenna
  • Meddelandestorlek 3-10 gånger mindre än JSON tack vare Varint-kodning
  • Hastighet för serialisering och deserialisering högre än textformat
  • .proto-scheman ger strikt typning och kodgenerering för 12+ språk
  • Bakåtkompatibilitet möjliggör API-evolution utan att bryta klienter
  • gRPC använder Protobuf som standardformat för mikrotjänstkommunikation
  • Idealisk för högt belastade system och mobila applikationer med begränsad trafik

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också