Perché Protobuf 3 ha reso facoltativi tutti i campi nei messaggi?


15

La sintassi 3 di protobuf ha reso tutti i campi facoltativi eliminando le parole chiave requirede optionaldalla precedente sintassi proto2. Leggendo alcuni commenti degli sviluppatori sembra che sia stato fatto per migliorare la compatibilità binaria avanti / indietro.

Ma per me, ciò potrebbe essere applicato semplicemente eseguendo il controllo delle versioni dei nomi dei pacchetti, dire com.example.messages.v1e quindi consentire ai client di implementare i deserializzatori che comprendono. Allo stesso tempo rimuove alcuni contratti dichiarati come un tipo utili dal punto di vista dell'ingegneria del software. Per esempio se ho

message Location {
   double latitude = 1;
   double longitude = 2;
}

In proto3 è possibile creare una metà supportata ma perfettamente valida Locationnon fornendo uno dei campi richiesti.

Non è un grosso svantaggio quando si crea un formato di serializzazione basato su schema per lo scambio di dati tra client? Non è peggio spostare un codice di convalida aggiuntivo su ciascun client verificando che tutti i campi richiesti abbiano valori validi?


Risposte:


13

proto3 apporta una serie di modifiche volte (come ho capito) a renderlo molto più utilizzabile in scenari multipiattaforma. Il tracciamento esplicito di "assegnato" vs "non assegnato ma che riporta il valore predefinito" può essere molto difficile da implementare su alcune delle piattaforme di destinazione e può anche essere confuso da usare. Come tale, proto3 adotta un approccio molto più semplice:

  • il valore predefinito implicito è il valore zero naturale (numeri / enum), false (booleani) o la stringa vuota (stringhe)
  • è consentito solo il valore predefinito implicito; non sono ammessi altri valori predefiniti
  • se un campo ha quel valore predefinito, non è serializzato; non importa se è stato assegnato esplicitamente a zero / false / stringa vuota vs mai assegnato
  • per questo motivo, non esiste un concetto di "obbligatorio", poiché "assegnato in modo esplicito un valore zero" e "mai assegnato un valore" sembrano identici

In proto3 è possibile creare una posizione supportata per metà ma perfettamente valida non fornendo uno dei campi richiesti.

L'altro valore è: zero. Il fatto che tu non l'abbia assegnato esplicitamente a zero è discutibile. Se questo sia desiderabile o meno dipende da te, ma ha senso per me ed è il modo in cui un sacco di "inizializzare un nuovo oggetto / struttura" funziona su una vasta gamma di piattaforme.

Non è peggio spostare un codice di convalida aggiuntivo su ciascun client verificando che tutti i campi richiesti abbiano valori validi?

Non c'è nulla da convalidare! Il layout è esattamente quello che sarebbe se il valore zero fosse assegnato esplicitamente. Se questo è legale, è legale. Se è illegale (perché zero non ha senso per te), è illegale; ma sarebbe illegale se fosse esplicito o implicito. La quantità di convalida coinvolta non cambia.

Non è un grosso svantaggio quando si crea un formato di serializzazione basato su schema per lo scambio di dati tra client?

Di solito no, specialmente perché la versione dello schema è esplicita. Se vuoi usare proto2: usa proto2. Nulla cambia automaticamente.


Mi chiedo cosa li compra "solo zero naturale come predefinito", dato che protobuf non è realmente utilizzabile senza un qualche tipo di schema. Garantire valori predefiniti coerenti non sembra molto più difficile che garantire schemi coerenti in primo luogo.
Codici InCos

1
@CodesInChaos è interessante, perché ho fatto protobuf senza schema per ... beh, per sempre :) in protobuf-net, si prevede che la maggior parte degli utenti sarà prima in codice e meno in schema. E interessante (almeno per me) la maggior parte delle strategie predefinite "Keep it simple, stupid" utilizzate da protobuf-net sono esattamente le stesse di quelle che proto3 ha scelto di utilizzare. Non ho intenzione di affermare che ciò convalida le mie decisioni casuali sui partigiani, ma ... lo fa totalmente :)
Marc Gravell

Considero una classe C # un tipo di schema e puoi certamente specificare valori predefiniti tramite attributi. Confrontalo con ad esempio msgpack o json, che può creare una struttura di dati significativa senza alcun tipo di schema.
Codici InCos

@CodesInChaos ha concordato e notato - e sì, protobuf-net osserverà e rispetterà tali dichiarazioni
Marc Gravell
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.