Protocol Buffers ( Protobuf ) es un formato de datos multiplataforma, gratuito y de código abierto que se utiliza para serializar datos estructurados. Es útil para desarrollar programas que se comunican entre sí a través de una red o para almacenar datos. El método implica un lenguaje de descripción de interfaz que describe la estructura de algunos datos y un programa que genera código fuente a partir de esa descripción para generar o analizar un flujo de bytes que representa los datos estructurados.
Google desarrolló Protocol Buffers para uso interno y proporcionó un generador de código para múltiples idiomas bajo una licencia de código abierto .
Los objetivos de diseño de Protocol Buffers enfatizaron la simplicidad y el rendimiento. En particular, se diseñó para que fuera más pequeño y más rápido que XML . [3]
En Google, Protocol Buffers se utiliza ampliamente para almacenar e intercambiar todo tipo de información estructurada. El método sirve como base para un sistema de llamada a procedimiento remoto (RPC) personalizado que se utiliza para casi todas las comunicaciones entre máquinas en Google. [4]
Protocol Buffers es similar a los protocolos Apache Thrift , Ion y Microsoft Bond, y ofrece una pila de protocolos RPC concreta para usar en servicios definidos llamados gRPC . [5]
Los esquemas de estructuras de datos (llamados mensajes ) y los servicios se describen en un archivo de definición de proto ( .proto
) y se compilan con protoc
. Esta compilación genera código que puede ser invocado por un remitente o destinatario de estas estructuras de datos. Por ejemplo, example.pb.cc
y example.pb.h
se generan a partir de example.proto
. Definen clases de C++ para cada mensaje y servicio en example.proto
.
Canónicamente, los mensajes se serializan en un formato de cable binario que es compacto, compatible con versiones anteriores y posteriores , pero no autodescriptivo (es decir, no hay forma de saber los nombres, el significado o los tipos de datos completos de los campos sin una especificación externa). No hay una forma definida de incluir o hacer referencia a dicha especificación externa (esquema) dentro de un archivo Protocol Buffers. La implementación oficialmente admitida incluye un formato de serialización ASCII, [6] pero este formato, aunque autodescriptivo, pierde el comportamiento de compatibilidad con versiones anteriores y posteriores, y por lo tanto no es una buena opción para aplicaciones que no sean la edición y depuración humanas. [7]
Aunque el propósito principal de Protocol Buffers es facilitar la comunicación en red, su simplicidad y velocidad hacen de Protocol Buffers una alternativa a las clases y estructuras de C++ centradas en datos, especialmente donde podría necesitarse interoperabilidad con otros lenguajes o sistemas en el futuro.
Los protobufs no tienen una única especificación. [8] El formato es más adecuado para fragmentos de datos pequeños que no superan unos pocos megabytes y se pueden cargar/enviar a una memoria de inmediato y, por lo tanto, no es un formato que se pueda transmitir. [9] La biblioteca no proporciona compresión de fábrica. El formato tampoco es compatible con lenguajes no orientados a objetos (por ejemplo, Fortran ). [10]
Un esquema para un uso particular de los buffers de protocolo asocia los tipos de datos con los nombres de los campos, utilizando números enteros para identificar cada campo. (Los datos del buffer de protocolo contienen solo los números, no los nombres de los campos, lo que permite ahorrar algo de ancho de banda y almacenamiento en comparación con los sistemas que incluyen los nombres de los campos en los datos).
// polilinea.proto sintaxis = "proto2" ; mensaje Punto { requerido int32 x = 1 ; requerido int32 y = 2 ; opcional cadena etiqueta = 3 ; } mensaje Línea { requerido Punto inicial = 1 ; requerido Punto final = 2 ; opcional cadena etiqueta = 3 ; } mensaje Polilínea { Punto repetido punto = 1 ; cadena opcional etiqueta = 2 ; }
El mensaje "Point" define dos elementos de datos obligatorios, x e y . La etiqueta del elemento de datos es opcional. Cada elemento de datos tiene una etiqueta. La etiqueta se define después del signo igual. Por ejemplo, x tiene la etiqueta 1.
Los mensajes "Línea" y "Polilínea", que utilizan puntos, demuestran cómo funciona la composición en los búferes de protocolo. La polilínea tiene un campo repetido y, por lo tanto, se comporta como un conjunto de puntos (de un número no especificado).
Este esquema puede compilarse posteriormente para su uso en uno o más lenguajes de programación. Google ofrece un compilador llamado protoc
que puede generar resultados para C++, Java o Python. Existen otros compiladores de esquemas disponibles en otras fuentes para crear resultados dependientes del lenguaje para más de 20 lenguajes diferentes. [11]
Por ejemplo, después de producir una versión C++ del esquema de búfer de protocolo anterior, un archivo de código fuente C++, polyline.cpp, puede usar los objetos de mensaje de la siguiente manera:
// polyline.cpp #include "polyline.pb.h" // generado al llamar al "protocolo polyline.proto" Línea * createNewLine ( const std :: string & name ) { // crea una línea desde (10, 20) hasta (30, 40) Línea * línea = new Línea ; línea -> mutable_start () -> set_x ( 10 ); línea -> mutable_start () -> set_y ( 20 ); línea -> mutable_end () -> set_x ( 30 ); línea -> mutable_end () -> set_y ( 40 ); línea -> set_label ( nombre ); return línea ; } Polilínea * createNewPolyline () { // crea una polilínea con puntos en (10,10) y (20,20) Polilínea * polilínea = new Polilínea ; Punto * punto1 = polilínea -> add_point (); punto1 -> set_x ( 10 ); punto1 -> set_y ( 10 ); Punto * punto2 = polilínea -> add_point (); punto2 -> set_x ( 20 ); punto2 -> set_y ( 20 ); return polilínea ; }
Protobuf 2.0 proporciona un generador de código para C++ , Java , C# , [12] y Python . [13]
Protobuf 3.0 proporciona un generador de código para C++ , Java (incluido JavaNano, un dialecto destinado a entornos de bajos recursos ), Python , Go , Ruby , Objective-C y C# . [14] También es compatible con JavaScript desde 3.0.0-beta-2. [15]
También hay implementaciones de terceros disponibles para Ballerina , [16] C , [17] [18] C++ , [19] Dart , Elixir , [20] [21] Erlang , [22] Haskell , [23] JavaScript , [24] Julia , [25] Nim , [26] Perl , PHP , Prolog , [27] [28] R , [29] Rust , [30] [31] [32] Scala , [33] y Swift . [34]