protocol protobuffers protobuf google buffers array protocol-buffers grpc proto3

protobuffers - Por qué es obligatorio y opcional se elimina en Protocol Buffers 3



protocol buffer list (2)

Recientemente estoy usando gRPC con proto3 , y he notado que lo required y lo optional se han eliminado en una nueva sintaxis.

¿Alguien podría explicar amablemente por qué se eliminan los requisitos / opcionales en proto3? Este tipo de restricciones simplemente parecen necesarias para hacer que la definición sea robusta.

sintaxis proto2:

message SearchRequest { required string query = 1; optional int32 page_number = 2; optional int32 result_per_page = 3; }

sintaxis proto3:

syntax = "proto3"; message SearchRequest { string query = 1; int32 page_number = 2; int32 result_per_page = 3; }


La utilidad de lo required ha estado en el centro de muchos debates y guerras de fuego. Grandes campamentos han existido en ambos lados. A un campamento le gustaba garantizar que un valor estuviera presente y estaba dispuesto a vivir con sus limitaciones, pero el otro campamento sentía required peligroso o inútil, ya que no se puede agregar ni eliminar con seguridad.

Permítanme explicar más del razonamiento por el required campos required deben usarse con moderación. Si ya está utilizando un protocolo, no puede agregar un campo obligatorio porque las aplicaciones antiguas no proporcionarán ese campo y las aplicaciones en general no manejan bien el error. Puede asegurarse de que todas las aplicaciones antiguas se actualicen primero, pero puede ser fácil cometer un error y no ayuda si almacena los protos en cualquier almacén de datos (incluso de corta duración, como memcached). El mismo tipo de situación se aplica al eliminar un campo requerido.

Muchos campos obligatorios fueron "obviamente" requeridos hasta que ... no lo fueron. Digamos que tiene un campo de id para un método Get . Eso es obviamente requerido. Excepto, más tarde puede que necesite cambiar la id de int a string, o int32 a int64. Eso requiere agregar un nuevo campo muchBetterId , y ahora le queda el viejo campo de id que debe especificarse, pero finalmente se ignora por completo.

Cuando se combinan esos dos problemas, la cantidad de campos required beneficiosos se vuelve limitada y los campamentos discuten sobre si todavía tiene valor. Los oponentes de required no estaban necesariamente en contra de la idea, sino de su forma actual. Algunos sugirieron desarrollar una biblioteca de validación más expresiva que pudiera verificar los required junto con algo más avanzado como name.length > 10 , al tiempo que se aseguraba de tener un mejor modelo de falla.

Proto3 en general parece favorecer la simplicidad, y la eliminación required es más simple. Pero tal vez sea más convincente, la eliminación required tenía sentido para proto3 cuando se combina con otras características, como la eliminación de la presencia de campo para primitivas y la eliminación de valores predeterminados primordiales.

No soy un desarrollador de protobuf y no tengo ninguna autoridad en el tema, pero todavía espero que la explicación sea útil.


Puede encontrar la explicación en este problema de Gotohub de protobuf :

Eliminamos los campos obligatorios en proto3 porque los campos obligatorios generalmente se consideran dañinos y violan la semántica de compatibilidad de protobuf. La idea general de usar protobuf es que le permite agregar / eliminar campos de la definición de su protocolo sin dejar de ser totalmente compatible con versiones anteriores o anteriores. Sin embargo, los campos obligatorios rompen esto. Nunca puede agregar con seguridad un campo requerido a una definición .proto, ni puede eliminar con seguridad un campo requerido existente porque ambas acciones rompen la compatibilidad del cable. Por ejemplo, si agrega un campo requerido a una definición .proto, los archivos binarios construidos con la nueva definición no podrán analizar los datos serializados usando la definición anterior porque el campo requerido no está presente en los datos antiguos. En un sistema complejo donde las definiciones .proto se comparten ampliamente en muchos componentes diferentes del sistema, agregar / eliminar campos obligatorios podría fácilmente derribar múltiples partes del sistema. Hemos visto problemas de producción causados ​​por esto varias veces y está prácticamente prohibido en todas partes dentro de Google para que cualquiera pueda agregar / eliminar campos obligatorios. Por esta razón, eliminamos completamente los campos obligatorios en proto3.

Después de eliminar "obligatorio", "opcional" es redundante, por lo que también eliminamos "opcional".