Protobuf — cos’è, formato dati binario e principio di funzionamento

Autore: IT Sectr Pubblicato: 2026-03-08 Tempo di lettura: 8 min

Protocol Buffers (Protobuf) è un formato binario di serializzazione per dati strutturati, sviluppato da Google per lo scambio efficiente di informazioni tra servizi. Il formato richiede una definizione preliminare dello schema in file .proto, dai quali viene generato il codice per vari linguaggi. Secondo la documentazione ufficiale di Google, Protobuf offre dimensioni dei messaggi da 3 a 10 volte inferiori rispetto a JSON. Protobuf è utilizzato in gRPC, Google Maps e migliaia di servizi interni.

Punti chiave

  • Protobuf — formato binario di Google per la serializzazione con rappresentazione compatta dei dati
  • Schemi .proto — descrizione rigorosamente tipizzata della struttura dati con compilazione in codice
  • Prestazioni — serializzazione da 3 a 10 volte più veloce e compatta di JSON
  • Retrocompatibilità — evoluzione dello schema senza rompere i client esistenti
  • gRPC — la principale tecnologia di trasporto per Protobuf nei microservizi

Cosa sono i Protocol Buffers?

Protocol Buffers è un meccanismo di serializzazione di dati strutturati sviluppato da Google, simile a JSON e XML, ma con una differenza fondamentale: i dati vengono codificati in formato binario. Ciò significa che un messaggio Protobuf non può essere letto a occhio nudo, ma occupa molto meno spazio e viene elaborato più velocemente delle controparti testuali.

Protobuf è stato creato internamente da Google per risolvere problemi di prestazioni nello scambio di dati tra servizi. Nel 2008, la tecnologia è diventata un progetto open source con supporto per molti linguaggi: C++, Java, Python, Go, JavaScript, Kotlin, Swift, Dart e altri. La versione proto3, rilasciata nel 2016, ha semplificato la sintassi e aggiunto il supporto per più linguaggi.

La differenza principale tra Protobuf e JSON è la necessità di definire uno schema prima di iniziare lo scambio di dati. Il file dello schema (.proto) descrive la struttura del messaggio: campi, tipi e numeri univoci dei campi. Da questo schema, il compilatore protoc genera classi nel linguaggio di destinazione per la serializzazione e deserializzazione.

Ecosistema Protobuf

  • gRPC — framework RPC ad alte prestazioni che utilizza Protobuf di default
  • protoc — compilatore di schemi .proto in codice per vari linguaggi di programmazione
  • Google API — la maggior parte delle API pubbliche di Google utilizza Protobuf
  • Envoy Proxy — utilizza Protobuf per la configurazione e lo scambio di dati

Architettura di Protobuf

L’architettura di Protobuf include tre componenti chiave: il linguaggio di definizione dello schema (.proto), il compilatore protoc e le librerie runtime per linguaggi specifici. Lo sviluppatore descrive la struttura dei dati in un file .proto, esegue la compilazione e riceve classi pronte per lavorare con questi dati.

Ogni campo in un messaggio Protobuf ha un numero univoco (field number) — non è un numero sequenziale, ma un tag utilizzato nel formato binario per identificare il campo. I numeri da 1 a 15 sono codificati in un byte, da 16 a 2047 in due byte. Pertanto, i campi importanti con alta frequenza di utilizzo dovrebbero essere numerati da 1 a 15 per ottimizzare le dimensioni.

Tipi di dati Protobuf

Protobuf supporta un’ampia gamma di tipi: scalari (int32, int64, float, double, bool, string, bytes), enumerazioni (enum), compositi (message) e tipi speciali (oneof, map). Ogni tipo ha una rappresentazione binaria specifica ottimizzata per il caso d’uso corrispondente.

Tipo .proto Tipo C++ Java/Kotlin Descrizione
double double double Numero a virgola mobile a 64 bit
float float float Numero a virgola mobile a 32 bit
int32 int32 int 32 bit, codifica a lunghezza variabile
int64 int64 long 64 bit, codifica a lunghezza variabile
string string String Stringa UTF-8
bytes string ByteString Byte arbitrari
bool bool boolean true / false

Vantaggi del formato binario

Protobuf offre tre vantaggi principali rispetto ai formati testuali: dimensione del messaggio, velocità di serializzazione e tipizzazione forte. Nei sistemi ad alto carico e nelle applicazioni mobili con traffico limitato, questi vantaggi diventano critici.

La rappresentazione binaria di Protobuf utilizza la codifica a lunghezza variabile (Varint) per i numeri: i numeri piccoli occupano 1 byte, quelli grandi fino a 10 byte. Ciò consente di codificare in modo efficiente identificatori, flag e contatori che occuperebbero decine di byte come stringhe di testo in JSON o XML. Ad esempio, il numero 150 in Protobuf occupa 2 byte, in JSON — 3 byte (come testo “150”), in XML — 3 byte + tag.

Un vantaggio aggiuntivo è la retrocompatibilità. L’aggiunta di un nuovo campo allo schema non rompe i vecchi client: ignorano semplicemente i campi sconosciuti. L’eliminazione di un campo richiede solo la riserva del suo numero per evitare collisioni future.

Definizione dello schema .proto

Lo schema .proto descrive la struttura dei dati in un linguaggio speciale. Il file inizia con la specifica della sintassi (proto3), del pacchetto e delle dipendenze di importazione. Ogni messaggio è definito con la parola chiave message con campi, dove ogni campo ha un tipo, un nome e un numero univoco.

Buone pratiche di schema: numeri di campo da 1 a 15 per i campi usati frequentemente, nomi significativi, raggruppamento dei campi correlati in un message separato, uso di oneof per i campi che possono essere solo una di diverse opzioni.

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

Messaggi annidati

I messaggi possono essere annidati: un campo profile di tipo Profile conterrà i dati utente al suo interno. Il supporto all’annidamento consente di descrivere strutture gerarchiche complesse senza duplicare le definizioni.

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

Generazione di codice da .proto

Il compilatore protoc converte i file .proto in codice sorgente nel linguaggio di destinazione. Per Kotlin/Java si usa il parametro --java_out, per Swift --swift_out (tramite il plugin Apple Swift Protobuf), per Dart --dart_out. Le classi generate contengono metodi builder per costruire messaggi e metodi di serializzazione/deserializzazione.

Su Android, per lavorare con Protobuf si usa il plugin com.google.protobuf versione 0.9+ in Gradle. Dopo aver aggiunto il plugin e specificato i file .proto, la build genera automaticamente classi Kotlin pronte per l’uso nell’applicazione.

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 {
    // Serializzazione in formato binario
    val bytes = user.toByteArray()

    // Deserializzazione dal formato binario
    return User.parseFrom(bytes)
}

Esempi di utilizzo di Protobuf

Protobuf è particolarmente efficace nell’architettura a microservizi e nelle applicazioni mobili. Consideriamo uno scenario tipico: un’applicazione mobile riceve un elenco di prodotti dal server tramite gRPC. Il messaggio Protobuf contiene le informazioni sul prodotto, tra cui identificatore, nome, prezzo e categoria. Il formato binario riduce le dimensioni della risposta da 5 a 8 volte rispetto a JSON.

Servizio gRPC in Kotlin

Esempio di un servizio gRPC con Protobuf lato server. Il servizio dichiara il metodo RPC GetProducts, che accetta una richiesta con parametri di paginazione e restituisce un elenco di prodotti. L’implementazione in Kotlin utilizza classi generate per lavorare con richieste e risposte.

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

Configurazione di Protobuf in un progetto Android

La configurazione di Protobuf in un progetto Android viene eseguita tramite il plugin Gradle com.google.protobuf. Il plugin esegue automaticamente il compilatore protoc durante la build e genera classi Kotlin dai file .proto. Per funzionare, è necessario aggiungere il plugin al build.gradle a livello di progetto e applicarlo nel modulo dell’applicazione.

Dopo aver configurato Gradle, i file .proto vengono inseriti nella directory src/main/proto. Il compilatore protoc li elabora durante ogni build, generando classi Kotlin che possono essere utilizzate nel codice dell’applicazione. È importante specificare correttamente le versioni di protobuf e protoc per evitare conflitti di dipendenza con altre librerie del progetto.

Per i progetti iOS, Protobuf viene collegato tramite CocoaPods o Swift Package Manager. Il plugin Swift Protobuf genera automaticamente strutture Swift conformi al protocollo Codable. Nei progetti Dart per Flutter, viene utilizzato il pacchetto protobuf e la compilazione viene eseguita tramite dart run protoc_plugin.

Domande frequenti

Qual è la differenza tra Protobuf e JSON?

Protobuf è un formato binario con schema obbligatorio, da 3 a 10 volte più compatto di JSON. JSON è testuale, leggibile dall’uomo e non richiede schema. Protobuf serializza e deserializza più velocemente ma richiede la compilazione di file .proto. JSON è più facile da debuggare e non richiede configurazione preliminare.

Come installare il compilatore protoc?

Scarica protoc dalla release GitHub di protobuf per la tua piattaforma. Per macOS, installa tramite brew install protobuf. Per Windows, scarica l’archivio zip e aggiungi protoc.exe al PATH. Per Android/Kotlin, usa il plugin Gradle com.google.protobuf, che esegue automaticamente la compilazione durante la build.

Cos’è gRPC e come si relaziona con Protobuf?

gRPC è un framework RPC ad alte prestazioni di Google che utilizza Protobuf come linguaggio di definizione dell’interfaccia (IDL) e formato di serializzazione. gRPC definisce servizi e metodi RPC in file .proto, genera codice client e server e supporta lo streaming e i protocolli binari.

Quali linguaggi supporta Protobuf?

Supportati ufficialmente da Google: C++, Java, Kotlin, Python, Go, Ruby, C#, PHP, JavaScript, Objective-C, Swift e Dart. La comunità ha sviluppato il supporto per Rust, TypeScript, Scala, Lua e altri linguaggi. Per lo sviluppo mobile, sono disponibili Kotlin/Java (Android) e Swift/Objective-C (iOS).

Come garantire la retrocompatibilità degli schemi?

Protobuf supporta la retrocompatibilità attraverso queste regole: non modificare i numeri dei campi, non eliminare i campi (usa reserved), aggiungi nuovi campi con nuovi numeri. I vecchi client ignorano i campi sconosciuti, i nuovi client ottengono valori predefiniti per i vecchi campi mancanti.

Riepilogo

  • Protocol Buffers — formato di serializzazione binaria di Google con schema dati obbligatorio
  • Dimensioni del messaggio da 3 a 10 volte inferiori a JSON grazie alla codifica Varint
  • Velocità di serializzazione e deserializzazione superiore ai formati di testo
  • Schemi .proto forniscono tipizzazione rigorosa e generazione di codice per 12+ linguaggi
  • Retrocompatibilità consente l’evoluzione delle API senza rompere i client
  • gRPC utilizza Protobuf come formato standard per la comunicazione tra microservizi
  • Ideale per sistemi ad alto carico e applicazioni mobili con traffico limitato

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche