Una buena es­tru­c­tu­ra­ción de los datos es básica a la hora de de­sa­rro­llar programas y páginas web. Si los datos de un proyecto están bien es­tru­c­tu­ra­dos, el resto de apli­ca­cio­nes podrán leerlos de manera fácil y precisa. En Internet, esto es es­pe­cia­l­me­n­te im­po­r­ta­n­te para los motores de búsqueda basados en texto, como Google, Bing o Yahoo, que pueden in­te­r­pre­tar el contenido de las páginas web de manera óptima gracias al uso de unos ma­r­ca­do­res adecuados y bien es­tru­c­tu­ra­dos.

En general, conviene es­tru­c­tu­rar los datos en el de­sa­rro­llo de software en pa­r­ti­cu­lar si los programas o servicios han de in­te­r­ca­m­biar los datos a través de in­te­r­fa­ces y es necesario pro­ce­sar­los a gran velocidad, tanto en las apli­ca­cio­nes web como de es­cri­to­rio. En los si­guie­n­tes párrafos, te contamos qué puede aportar el formato de se­ria­li­za­ción Protocol Buffers (Protobuf) a este proceso y en qué se di­fe­re­n­cia este sistema de es­tru­c­tu­ra­ción de JSONP, la al­te­r­na­ti­va más conocida.

¿Qué es Protocol Buffers?

Protocol Buffers (abreviado como Protobuf) es un formato de in­te­r­ca­m­bio de datos de­sa­rro­lla­do ori­gi­na­l­me­n­te para uso interno en Google y lanzado al gran público por la empresa en 2008 como proyecto de código abierto (en parte, con licencia Apache 2.0). Este formato binario permite a las apli­ca­cio­nes almacenar e in­te­r­ca­m­biar datos es­tru­c­tu­ra­dos fá­ci­l­me­n­te, incluso si los programas están co­m­pi­la­dos en di­fe­re­n­tes lenguajes. Entre los lenguajes de pro­gra­ma­ción co­m­pa­ti­bles, se incluyen los si­guie­n­tes:

  • C#
  • C++
  • Go
  • Objective-C
  • Java
  • Python
  • Ruby

Protobuf se utiliza en co­m­bi­na­ción con, entre otros, HTTP y RPC (Remote Procedure Call o llamada a pro­ce­di­mie­n­to remoto) para llevar a cabo el proceso de co­mu­ni­ca­ción cliente-servidor local y remota, en pa­r­ti­cu­lar para describir las in­te­r­fa­ces ne­ce­sa­rias para ello. La es­tru­c­tu­ra del protocolo también se denomina gRPC.

72mPlAfHIjs.jpg Para mostrar este video, se requieren cookies de terceros. Puede acceder y cambiar sus ajustes de cookies aquí.

¿Qué ventajas ofrece Protocol Buffers de Google?

Google se centró es­pe­cia­l­me­n­te en dos factores durante el de­sa­rro­llo de Protobuf: la si­m­pli­ci­dad y el re­n­di­mie­n­to. Se pretendía que este formato, que solo se utilizaba in­te­r­na­me­n­te en la propia empresa en aquel momento, su­s­ti­tu­ye­ra al formato XML, que pre­se­n­ta­ba ca­ra­c­te­rí­s­ti­cas similares. Ac­tua­l­me­n­te, Protobuf también compite con otras so­lu­cio­nes, como JSON(P) o Fla­t­Bu­f­fe­rs. Si ana­li­za­mos los elementos y puntos fuertes de este sistema de es­tru­c­tu­ra­ción y los co­m­pa­ra­mos con las demás opciones, Protocol Buffers se revela como el formato más adecuado para muchos proyectos por los si­guie­n­tes motivos:

Esquemas claros y mu­l­ti­apli­ca­ción

La clave del éxito de cualquier apli­ca­ción es tener un sistema de base de datos bien or­ga­ni­za­do. Por ello, se suele prestar mucha atención a es­tru­c­tu­rar­lo co­rre­c­ta­me­n­te durante el de­sa­rro­llo del software, incluidos los datos que contiene. Sin embargo, en cuanto los datos se envían a un servicio externo, las es­tru­c­tu­ras su­b­ya­ce­n­tes se acaban perdiendo. Mediante Protobuf, como los datos se codifican una sola vez, nos ase­gu­ra­mos de que el proyecto los reenvía ma­n­te­nie­n­do la es­tru­c­tu­ra original y sin romperla.

Co­m­pa­ti­bi­li­dad con versiones an­te­rio­res y po­s­te­rio­res

Utilizar Protobuf nos ahorra la molestia de realizar co­m­pro­ba­cio­nes de versión, lo que suele asociarse con el código “sucio” (es decir, código mal or­ga­ni­za­do y difícil de leer). Para mantener la co­m­pa­ti­bi­li­dad, tanto con las versiones an­te­rio­res, como con las nuevas, Protocol Buffers utiliza campos numerados que sirven como puntos de re­fe­re­n­cia para los servicios que acceden a ellas. De esta manera, a la hora de publicar nuevas ca­ra­c­te­rí­s­ti­cas y funciones, no siempre es necesario adaptar todo el código.

Fle­xi­bi­li­dad y comodidad

Al codificar con Protobuf, se recurre au­to­má­ti­ca­me­n­te a mo­di­fi­ca­do­res (de tipo obli­ga­to­rio, opcional o repetido) que facilitan co­n­si­de­ra­ble­me­n­te el trabajo de pro­gra­ma­ción. Este sistema permite es­ta­ble­cer la forma de la es­tru­c­tu­ra de los datos a nivel de esquema, de manera que los datos de im­ple­me­n­ta­ción de las clases uti­li­za­das para los di­fe­re­n­tes lenguajes de pro­gra­ma­ción se regulan au­to­má­ti­ca­me­n­te. También es posible cambiar el estado en cualquier momento, por ejemplo, de “obli­ga­to­rio” a “opcional”. Asimismo, Protobuf permite regular la tra­n­s­fe­re­n­cia de las es­tru­c­tu­ras de datos: la co­di­fi­ca­ción de las es­tru­c­tu­ras genéricas de solicitud y respuesta garantiza que la tra­n­s­fe­re­n­cia de datos entre varios servicios sea fácil, flexible y segura.

Menos código re­pe­ti­ti­vo

El código re­pe­ti­ti­vo (en inglés, boi­le­r­pla­te code) tiene un papel más o menos decisivo en la pro­gra­ma­ción, de­pe­n­die­n­do del tipo y la co­m­ple­ji­dad del proyecto. Bá­si­ca­me­n­te, se trata de bloques de código re­uti­li­za­bles que se deben im­ple­me­n­tar muchas veces en el programa y que, por lo general, se in­tro­du­cen casi sin al­te­ra­cio­nes. Por ejemplo, este tipo de código suele uti­li­zar­se para preparar el uso de funciones de bi­blio­te­cas. Aunque el código re­pe­ti­ti­vo es es­pe­cia­l­me­n­te habitual en los lenguajes Ja­va­S­cri­pt, PHP, HTML y CSS, este no ayuda en absoluto al re­n­di­mie­n­to de las apli­ca­cio­nes web. Un esquema adecuado de Procotol Buffers ayuda a reducir el código re­pe­ti­ti­vo y, por lo tanto, a mejorar el re­n­di­mie­n­to del proyecto a largo plazo.

Fácil in­te­ro­pe­ra­bi­li­dad entre lenguajes

En el estándar actual, no es lo más habitual escribir las apli­ca­cio­nes en un solo lenguaje, sino combinar módulos o partes de programas escritos en los lenguajes más diversos. Protobuf si­m­pli­fi­ca co­n­si­de­ra­ble­me­n­te la in­ter­ac­ción entre todos los elementos del código: si se añaden elementos nuevos, cuyo lenguaje difiere del lenguaje actual del proyecto, el sistema si­m­ple­me­n­te los traduce al lenguaje de destino co­rre­s­po­n­die­n­te uti­li­za­n­do el generador de código apropiado, por lo que el esfuerzo que debemos dedicarle se reduce al mínimo. Ob­via­me­n­te, el requisito previo es que los lenguajes que uti­li­ce­mos sean co­m­pa­ti­bles con Protobuf ―ya sea de forma pre­de­te­r­mi­na­da, como los que ya hemos me­n­cio­na­do, o mediante un co­m­ple­me­n­to de otro proveedor.

Protobuf vs. JSON: co­m­pa­ra­ti­va de ambos formatos

Cuando de­sa­rro­lló Protocol Buffers, Google pretendía co­n­ve­r­ti­r­lo en una al­te­r­na­ti­va a XML (del inglés ex­te­n­si­ble markup language, o lenguaje de marcado ex­te­n­si­ble). Lo cierto es que logró superarlo de muchas maneras: es­tru­c­tu­rar los datos con Protobuf no solo tiende a ser más fácil, sino que también garantiza obtener una es­tru­c­tu­ra de datos entre tres y diez veces más pequeña y entre 20 y 100 veces más rápida que una es­tru­c­tu­ra XML co­m­pa­ra­ble, según afirma la propia compañía.

Protocol Buffers también suele co­m­pa­rar­se con el lenguaje de marcado JSON (Ja­va­S­cri­pt Object Notation) de Ja­va­S­cri­pt, aunque cabe mencionar que ambas te­c­no­lo­gías fueron diseñadas con objetivos di­fe­re­n­tes: JSON es un formato de texto sencillo basado en Ja­va­S­cri­pt para in­te­r­ca­m­biar mensajes, siendo co­m­pa­ti­ble con prá­c­ti­ca­me­n­te todos los lenguajes de pro­gra­ma­ción ha­bi­tua­les. La fu­n­cio­na­li­dad de Protobuf abarca más que el formato de texto, porque esta te­c­no­lo­gía de Google también ofrece varias reglas y he­rra­mie­n­tas para definir e in­te­r­ca­m­biar los mensajes. Además, Protobuf también supera a JSON en términos de re­n­di­mie­n­to si ana­li­za­mos el envío de los mensajes en general. En cualquier caso, ambos sistemas de es­tru­c­tu­ra­ción tienen sus ventajas e in­co­n­ve­nie­n­tes, como verás en la siguiente tabla co­m­pa­ra­ti­va:

Protobuf JSON
De­sa­rro­lla­dor Google Douglas Crockford
Función Formato de marcado para datos es­tru­c­tu­ra­dos (al­ma­ce­na­mie­n­to y tra­n­s­mi­sión) y bi­blio­te­ca Formato de marcado para datos es­tru­c­tu­ra­dos (al­ma­ce­na­mie­n­to y tra­n­s­mi­sión)
Formato binario Sí No
Es­ta­n­da­ri­za­ción No Sí
Legible para el ser humano En parte Sí
Comunidad/do­cu­me­n­ta­ción Comunidad pequeña; manuales en línea ex­te­n­si­bles Comunidad enorme, buena do­cu­me­n­ta­ción oficial y diversos tu­to­ria­les en línea, etc.

Como habrás deducido, si necesitas un formato de se­ria­li­za­ción bien do­cu­me­n­ta­do que almacene y tra­n­s­fie­ra los datos es­tru­c­tu­ra­dos de forma legible para el ser humano, deberás recurrir a JSON en lugar de Protocol Buffers, es­pe­cia­l­me­n­te en los casos en que la parte del lado del servidor de la apli­ca­ción esté escrita en Ja­va­S­cri­pt y una gran parte de los datos sea procesada di­re­c­ta­me­n­te por los na­ve­ga­do­res de manera pre­de­te­r­mi­na­da. Sin embargo, cuando haya que favorecer la fle­xi­bi­li­dad y el re­n­di­mie­n­to de la es­tru­c­tu­ra de los datos, Protobuf pro­ba­ble­me­n­te sea la solución más adecuada y eficiente.

Tutorial: ejemplo práctico de Protobuf con Java

El uso de Protocol Buffers puede marcar la di­fe­re­n­cia en muchos proyectos de software, pero, como suele ser el caso, primero conviene conocer y saber aplicar las ca­ra­c­te­rí­s­ti­cas es­pe­cia­les y los trucos si­n­tá­c­ti­cos de esta te­c­no­lo­gía de se­ria­li­za­ción. En el tutorial que figura a co­n­ti­nua­ción, te en­se­ña­re­mos a dar tus primeros pasos con Protobuf y podrás hacerte una idea de cómo se es­tru­c­tu­ra la sintaxis y el in­te­r­ca­m­bio de mensajes en este sistema: desde la de­fi­ni­ción de tu propio formato mediante un archivo .proto hasta la co­m­pi­la­ción de las es­tru­c­tu­ras de Protocol Buffers. Como ejemplo, te pro­po­ne­mos una apli­ca­ción sencilla: una agenda de contactos en Java, que puede leer los datos de contacto de un archivo y es­cri­bi­r­los en otro. A cada registro de la agenda se le asignan los pa­rá­me­tros “nombre”, “ID”, “dirección de correo ele­c­tró­ni­co” y “número de teléfono”.

Definir nuestro propio formato de datos en el archivo .proto

En primer lugar, debes describir todas las es­tru­c­tu­ras de datos que desees im­ple­me­n­tar con Protocol Buffers en el archivo .proto, el archivo de co­n­fi­gu­ra­ción estándar de este formato de se­ria­li­za­ción. Para cada es­tru­c­tu­ra que quieras se­ria­li­zar en este archivo ―es decir, in­tro­du­cir siguiendo una es­tru­c­tu­ra― no tienes más que añadir un mensaje (en inglés, message). Después, debes es­pe­ci­fi­car los nombres y tipos para cada campo de este mensaje y añadir el mo­di­fi­ca­dor o mo­di­fi­ca­do­res que quieras. Es obli­ga­to­rio asignar un mo­di­fi­ca­dor a cada campo.

Para nuestra agenda de contactos en Java, esta podría ser una posible asi­g­na­ción de las es­tru­c­tu­ras de datos en el archivo .proto:

syntax = "proto3";
package tutorial;
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
message Person {
    required string name = 1;
    required int32 id = 2;
    optional string email = 3;
    enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
    }
    message PhoneNumber {
        required string number = 1;
        optional PhoneType type = 2 [default = HOME];
    }
    repeated PhoneNumber phones = 4;
}
message AddressBook {
    repeated Person people = 1;
}

La sintaxis de Protocol Buffers recuerda mucho a la de C++ o a la de Java: en primer lugar, se es­pe­ci­fi­ca la co­rre­s­po­n­die­n­te versión de Protobuf, en este caso, proto3, seguida de la de­s­cri­p­ción del paquete de software cuyos datos se desea es­tru­c­tu­rar, que siempre incluye un nombre único (aquí, tutorial). En nuestro ejemplo de código, se añaden también las dos opciones es­pe­cí­fi­cas de Java java_package (paquete de Java en el que se guardan las clases generadas) y java_outer_classname (que define el nombre bajo el cual se designan las clases).

A co­n­ti­nua­ción, figuran los mensajes de Protobuf, que pueden estar co­m­pue­s­tos por un número ilimitado de campos. Entre ellos, di­s­po­ne­mos de los tipos de datos típicos como bool, int32, float, double o string, algunos de los cuales también se utilizan en el ejemplo. Como ya hemos me­n­cio­na­do, a cada campo se le debe asignar al menos uno de los si­guie­n­tes tres mo­di­fi­ca­do­res:

  • required: indica que es obli­ga­to­rio asignar un valor al campo. En caso contrario, el estado del mensaje es uni­ni­tia­li­zed, es decir, sin ini­cia­li­zar o sin enviar.
  • optional: en los campos op­cio­na­les, es posible indicar un valor, aunque no es necesario. Si no hay ningún valor, se utiliza uno definido como estándar. En el código de nuestro tutorial, por ejemplo, se introduce el valor pre­de­te­r­mi­na­do HOME (número de teléfono fijo) para el tipo de número de teléfono.
  • repeated: los campos con este mo­di­fi­ca­dor pueden repetirse un número in­de­fi­ni­do de veces (incluso ninguna).

En el foro para de­sa­rro­lla­do­res de Google, en­co­n­tra­rás in­fo­r­ma­ción detallada sobre cómo definir tu propio formato de datos con Protocol Buffers.

Compilar nuestro propio esquema de Protobuf

Una vez hayas definido las es­tru­c­tu­ras de datos en el archivo .proto, debes generar las clases ne­ce­sa­rias para la lectura y la escritura de los mensajes de Protobuf. Para ello, aplica el co­m­pi­la­dor de Protocol Buffers (Protoc) al archivo de co­n­fi­gu­ra­ción. Si aún no lo has instalado, puedes descargar la versión ac­tua­li­za­da en el re­po­si­to­rio oficial de GitHub. De­s­co­m­pri­me el archivo .zip en la carpeta que quieras y, a co­n­ti­nua­ción, inicia el co­m­pi­la­dor (ubicado en la carpeta “bin”) haciendo doble clic.

Nota

Asegúrate de descargar la edición correcta del co­m­pi­la­dor de Protobuf, ya que Protoc está di­s­po­ni­ble para ar­qui­te­c­tu­ras de 32 y 64 bits (Windows, Linux o macOS.

Fi­na­l­me­n­te, debes es­pe­ci­fi­car lo siguiente:

  • Di­re­c­to­rio fuente en el que se encuentra el código del programa (en nuestro ejemplo, la carpeta “SRC_DIR”)
  • Di­re­c­to­rio de destino en el que se guardará el código generado (aquí, la carpeta “DST_DIR”)
  • Ruta del archivo .proto

Como tu intención es generar clases Java, utiliza también la opción --java_out (también hay opciones similares di­s­po­ni­bles para el resto de lenguajes co­m­pa­ti­bles). El comando de co­m­pi­la­ción completo se vería así:

protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
Consejo

Google pro­po­r­cio­na un tutorial detallado de Protobuf con Java, que también explica cómo tra­n­s­fe­rir mensajes a través de Protocol Buffers (lectura/escritura), en un apartado dedicado en Google De­ve­lo­pe­rs, la página para de­sa­rro­lla­do­res de proyectos de software que ofrece el gigante in­fo­r­má­ti­co. Allí también figuran las in­s­tru­c­cio­nes para trabajar con el resto de lenguajes co­m­pa­ti­bles, como C++, Go o Python.

Ir al menú principal