Warum hat Protobuf 3 alle Felder in den Nachrichten optional gemacht?


15

Die Syntax 3 von protobuf machte alle Felder optional requiredund optionallöschte die Schlüsselwörter und aus der vorherigen Proto2-Syntax. Einige Kommentare von Entwicklern lassen vermuten, dass dies zur Verbesserung der binären Vorwärts- / Rückwärtskompatibilität getan wurde.

Aber für mich könnte das durchgesetzt werden, indem einfach die Paketnamen versioniert werden com.example.messages.v1und dann die Clients Deserialisierer implementieren, die sie verstehen. Gleichzeitig werden einige Verträge entfernt, die aus Sicht der Softwareentwicklung als nützlich eingestuft werden. Zum Beispiel, wenn ich habe

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

In proto3 ist es möglich, ein halbgesichertes, aber vollkommen gültiges Feld zu erstellen, Locationindem eines der erforderlichen Felder nicht angegeben wird.

Ist das nicht ein großer Nachteil beim Erstellen eines schemabasierten Serialisierungsformats für den Datenaustausch zwischen Clients? Ist es nicht schlimmer, zusätzlichen Validierungscode auf jeden Client zu verschieben und zu überprüfen, ob alle erforderlichen Felder gültige Werte enthalten?


Antworten:


13

proto3 nimmt eine Reihe von Änderungen vor, die darauf abzielen (wie ich es verstehe), es in plattformübergreifenden Szenarien viel benutzerfreundlicher zu machen . Die explizite Verfolgung von "zugewiesen" und "nicht zugewiesen", aber das Melden des Standardwerts "kann auf einigen Zielplattformen sehr schwierig zu implementieren und auch verwirrend sein. Aus diesem Grund geht proto3 viel einfacher vor:

  • Der implizite Standardwert ist der natürliche Nullwert (Zahlen / Aufzählungen), false (Boolesche Werte) oder die leere Zeichenfolge (Zeichenfolgen).
  • Nur der implizite Standardwert ist zulässig. Andere Standardwerte sind nicht zulässig
  • Wenn ein Feld diesen Standardwert hat, wird es nicht serialisiert. Es spielt keine Rolle, ob es explizit zu Null / Falsch / Leer-Zeichenfolge im Vergleich zu Nie zugewiesen wurde
  • Aus diesem Grund gibt es kein Konzept von "erforderlich", da "explizit einen Nullwert zugewiesen" und "nie einen Wert zugewiesen" identisch aussehen

In proto3 ist es möglich, einen halb gesicherten, aber vollständig gültigen Standort zu erstellen, indem Sie keines der erforderlichen Felder angeben.

Der andere Wert ist: Null. Die Tatsache, dass Sie es nicht explizit auf Null gesetzt haben, ist umstritten. Ob dies wünschenswert ist oder nicht, liegt bei Ihnen, aber für mich ist es sinnvoll, wie viel "Initialisieren eines neuen Objekts / einer neuen Struktur" auf einer Vielzahl von Plattformen funktioniert.

Ist es nicht schlimmer, zusätzlichen Validierungscode auf jeden Client zu verschieben und zu überprüfen, ob alle erforderlichen Felder gültige Werte enthalten?

Es gibt nichts zu validieren! Das Layout ist genau das, was es wäre, wenn der Wert Null explizit zugewiesen würde. Wenn das legal ist, ist es legal. Wenn es illegal ist (weil Null für Sie keinen Sinn ergibt), ist es illegal. aber es wäre illegal, ob es explizit oder implizit war. Der Umfang der Validierung ändert sich nicht.

Ist das nicht ein großer Nachteil beim Erstellen eines schemabasierten Serialisierungsformats für den Datenaustausch zwischen Clients?

Nicht normalerweise, nein ... zumal die Schemaversion explizit ist. Wenn Sie proto2 verwenden möchten: Verwenden Sie proto2. Nichts ändert sich automatisch.


Ich frage mich, was "nur natürliche Null als Standard" sie kauft, da Protobuf ohne irgendeine Art von Schema nicht wirklich verwendbar ist. Das Sicherstellen einheitlicher Standardeinstellungen ist nicht viel schwieriger als das Sicherstellen einheitlicher Schemas.
CodesInChaos

1
@CodesInChaos das ist interessant, weil ich für ... na ja, für immer schemaloses protobuf gemacht habe :) in protobuf-net wird erwartet, dass die meisten Benutzer Code-first und schemaloses sind . Und interessanterweise (zumindest für mich) stimmen die meisten Standardstrategien von protobuf-net genau mit denen von proto3 überein. Ich werde nicht behaupten, dass dies meine zufälligen Partisanenentscheidungen bestätigt, aber ... das tut es total :)
Marc Gravell

Ich betrachte eine C # -Klasse als eine Art Schema, und Sie können sicher Standardwerte über Attribute angeben. Vergleichen Sie dies beispielsweise mit msgpack oder json, mit denen eine aussagekräftige Datenstruktur ohne jede Art von Schema erstellt werden kann.
CodesInChaos

@CodesInChaos stimmte zu und notierte - und ja, protobuf-net wird solche Erklärungen beachten und respektieren
Marc Gravell
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.