web-dev-qa-db-fra.com

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

La syntaxe 3 de protobuf a rendu tous les champs facultatifs en supprimant les mots clés required et optional de la syntaxe proto2 précédente. 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, par exemple com.example.messages.v1 puis laissez les clients implémenter les 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 Location à moitié sauvegardé mais parfaitement valide en 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?

16
tonicebrian

proto3 fait un 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 indiquant 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 par défaut implicite est la valeur zéro naturelle (nombres/énumérations), false (booléens) ou la chaîne vide (chaînes)
  • seulement 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é affecté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 affecté à 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 comment beaucoup d'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.

15
Marc Gravell