Pourquoi Protobuf 3 a rendu tous les champs des messages facultatifs?

15

La syntaxe 3 de protobuf a rendu tous les champs facultatifs en supprimant les mots clés requiredet la optionalsyntaxe précédente de proto2. En lisant certains commentaires des développeurs, il semble que cela ait été fait pour améliorer la compatibilité binaire avant / arrière.

Mais pour moi, cela pourrait être appliqué en versionnant simplement les noms des packages, en disant com.example.messages.v1puis en laissant les clients implémenter des désérialiseurs qu'ils comprennent. En même temps, il supprime certains contrats définis comme un type qui sont utiles du point de vue de l'ingénierie logicielle. Par exemple, si j'ai

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

Dans proto3, il est possible de créer un demi-dossier mais parfaitement valide Locationen ne fournissant pas l'un des champs requis.

N'est-ce pas un gros inconvénient lors de la création d'un format de sérialisation basé sur un schéma pour l'échange de données entre clients? N'est-il pas pire de déplacer du code de validation supplémentaire vers chaque client en vérifiant que tous les champs obligatoires ont des valeurs valides?

tonicebrian
la source
leanpub.com/esversioning
VoiceOfUnreason

Réponses:

13

proto3 apporte un certain nombre de changements visant (si je comprends bien) à le rendre beaucoup plus utilisable dans les scénarios multiplateformes. Le suivi explicite de «attribué» par rapport à «non attribué mais signalant la valeur par défaut» peut être très difficile à mettre en œuvre sur certaines des plates-formes cibles, et peut également être déroutant à utiliser. En tant que tel, proto3 adopte une approche beaucoup plus simple:

  • la valeur implicite par défaut est la valeur zéro naturelle (nombres / énumérations), false (booléens) ou la chaîne vide (chaînes)
  • seule la valeur implicite par défaut est autorisée; aucune autre valeur par défaut n'est autorisée
  • si un champ a cette valeur par défaut, il n'est pas sérialisé; peu importe si elle a été attribuée explicitement à zéro / fausse / chaîne vide vs jamais affectée
  • à cause de cela, il n'y a pas de concept de "requis", car "assigné explicitement une valeur zéro" et "jamais assigné une valeur" semblent identiques

Dans proto3, il est possible de créer un emplacement à moitié soutenu mais parfaitement valide en ne fournissant pas l'un des champs requis.

L'autre valeur est: zéro. Le fait que vous ne l'ayez pas explicitement attribué à zéro est sans objet. C'est à vous de décider si cela est souhaitable ou non, mais cela a du sens pour moi et c'est la façon dont beaucoup de "initialiser un nouvel objet / structure" fonctionne sur un large éventail de plates-formes.

N'est-il pas pire de déplacer du code de validation supplémentaire vers chaque client en vérifiant que tous les champs obligatoires ont des valeurs valides?

Il n'y a rien à valider! La disposition est exactement ce qu'elle serait si la valeur zéro était explicitement affectée. Si c'est légal, c'est légal. Si c'est illégal (parce que zéro n'a pas de sens pour vous), c'est illégal; mais il serait illégal qu'il soit explicite ou implicite. Le montant de validation impliqué ne change pas.

N'est-ce pas un gros inconvénient lors de la création d'un format de sérialisation basé sur un schéma pour l'échange de données entre clients?

Pas habituellement, non ... d'autant plus que la version du schéma est explicite. Si vous souhaitez utiliser proto2: utilisez proto2. Rien ne change automatiquement.

Marc Gravell
la source
Je me demande ce que "uniquement le zéro naturel par défaut" les achète, car protobuf n'est pas vraiment utilisable sans une sorte de schéma. Garantir des valeurs par défaut cohérentes ne semble pas beaucoup plus difficile que d'assurer des schémas cohérents en premier lieu.
CodesInChaos
1
@CodesInChaos c'est intéressant, parce que je fais du protobuf sans schéma depuis ... enfin, pour toujours :) dans protobuf-net, on s'attend à ce que la plupart des utilisateurs soient sans code et sans schéma. Et ce qui est intéressant (pour moi, au moins), la plupart des stratégies par défaut «garder les choses simples et stupides» utilisées par protobuf-net sont exactement les mêmes que ce que proto3 a choisi d'utiliser. Je ne vais pas prétendre que cela valide mes décisions partisanes aléatoires, mais ... c'est tout à fait le cas :)
Marc Gravell
Je considère une classe C # comme une sorte de schéma et vous pouvez certainement spécifier des valeurs par défaut via des attributs. Comparez cela avec, par exemple, msgpack ou json, qui peuvent créer une structure de données significative sans aucun type de schéma.
CodesInChaos
@CodesInChaos a accepté et noté - et oui, protobuf-net observera et respectera ces déclarations
Marc Gravell