# Protobuf: estructurar el código con Protocol Buffers

Una buena **estructuración de los datos** es básica a la hora de desarrollar programas y páginas web. Si los datos de un proyecto están bien estructurados, el resto de aplicaciones podrán leerlos de manera fácil y precisa. En Internet, esto es especialmente importante para los **motores de búsqueda basados en texto**, como Google, Bing o Yahoo, que pueden interpretar el contenido de las páginas web de manera óptima gracias al uso de unos marcadores adecuados y bien estructurados.

En general, conviene [estructurar los datos](https://www.ionos.mx/digitalguide/paginas-web/creacion-de-paginas-web/los-datos-estructurados-en-la-web-semantica/) en el desarrollo de software en particular si los programas o servicios han de **intercambiar los datos a través de interfaces** y es necesario procesarlos a gran velocidad, tanto en las aplicaciones web como de escritorio. En los siguientes párrafos, te contamos qué puede aportar el formato de serialización Protocol Buffers (Protobuf) a este proceso y en qué se diferencia este sistema de estructuración de [JSONP](https://www.ionos.mx/digitalguide/paginas-web/desarrollo-web/jsonp/), la alternativa más conocida.

## ¿Qué es Protocol Buffers?

Protocol Buffers (abreviado como Protobuf) es un **formato de intercambio de datos** desarrollado originalmente 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 aplicaciones **almacenar** **e intercambiar** **datos estructurados** fácilmente, incluso si los programas están compilados en diferentes lenguajes. Entre los **lenguajes** de programación compatibles, se incluyen los siguientes:

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

Protobuf se utiliza en combinación con, entre otros, HTTP y RPC (Remote Procedure Call o llamada a procedimiento remoto) para llevar a cabo el proceso de **comunicación cliente-servidor** local y remota, en particular para describir las interfaces necesarias para ello. La estructura del protocolo también se denomina [gRPC](https://www.ionos.mx/digitalguide/servidores/know-how/que-es-grpc/ "Qué es gRPC").

## ¿Qué ventajas ofrece Protocol Buffers de Google?

Google se centró especialmente en dos factores durante el desarrollo de Protobuf: la **simplicidad** y el **rendimiento**. Se pretendía que este formato, que solo se utilizaba internamente en la propia empresa en aquel momento, sustituyera al formato XML, que presentaba características similares. Actualmente, Protobuf también compite con otras soluciones, como JSON(P) o FlatBuffers. Si analizamos los **elementos y puntos fuertes de este sistema de estructuración** y los comparamos con las demás opciones, Protocol Buffers se revela como el formato más adecuado para muchos proyectos por los siguientes motivos:

### Esquemas claros y multiaplicación

La clave del éxito de cualquier aplicación es tener un **sistema de base de datos bien organizado**. Por ello, se suele prestar mucha atención a estructurarlo correctamente durante el desarrollo del software, incluidos los datos que contiene. Sin embargo, en cuanto los datos se envían a un servicio externo, las **estructuras subyacentes** se acaban perdiendo. Mediante Protobuf, como los datos se codifican una sola vez, nos aseguramos de que el proyecto los reenvía manteniendo la estructura original y sin romperla.

### Compatibilidad con versiones anteriores y posteriores

Utilizar Protobuf nos ahorra la molestia de **realizar comprobaciones de versión**, lo que suele asociarse con el código “sucio” (es decir, código mal organizado y difícil de leer). Para **mantener** la compatibilidad, tanto con las versiones anteriores, como con las nuevas, Protocol Buffers utiliza campos numerados que sirven como puntos de referencia para los servicios que acceden a ellas. De esta manera, a la hora de publicar nuevas características y funciones, no siempre es necesario adaptar todo el código.

### Flexibilidad y comodidad

Al codificar con Protobuf, se recurre automáticamente a **modificadores** (de tipo obligatorio, opcional o repetido) que facilitan considerablemente el trabajo de programación. Este sistema permite **establecer** la forma de la **estructura de los datos a nivel de esquema**, de manera que los datos de implementación de las clases utilizadas para los diferentes lenguajes de programación se regulan automáticamente. También es posible cambiar el estado en cualquier momento, por ejemplo, de “obligatorio” a “opcional”. Asimismo, Protobuf permite regular la transferencia de las estructuras de datos: la **codificación de las estructuras genéricas de solicitud y respuesta** garantiza que la transferencia de datos entre varios servicios sea fácil, flexible y segura.

### Menos código repetitivo

El código repetitivo (en inglés, *boilerplate code*) tiene un papel más o menos decisivo en la programación, dependiendo del tipo y la complejidad del proyecto. Básicamente, se trata de **bloques de código reutilizables** que se deben implementar muchas veces en el programa y que, por lo general, se introducen **casi sin alteraciones**. Por ejemplo, este tipo de código suele utilizarse para preparar el uso de funciones de bibliotecas. Aunque el código repetitivo es especialmente habitual en los lenguajes JavaScript, PHP, HTML y CSS, este no ayuda en absoluto al rendimiento de las aplicaciones web. Un esquema adecuado de Procotol Buffers ayuda a reducir el código repetitivo y, por lo tanto, a mejorar el rendimiento del proyecto a largo plazo.

### Fácil interoperabilidad entre lenguajes

En el estándar actual, no es lo más habitual escribir las aplicaciones en un solo lenguaje, sino combinar módulos o partes de programas escritos en los lenguajes más diversos. Protobuf simplifica considerablemente la **interacción entre todos los elementos del código**: si se añaden elementos nuevos, cuyo lenguaje difiere del lenguaje actual del proyecto, el sistema simplemente los traduce al lenguaje de destino correspondiente utilizando el generador de código apropiado, por lo que **el esfuerzo** que debemos dedicarle **se reduce al mínimo**. Obviamente, el requisito previo es que los lenguajes que utilicemos sean compatibles con Protobuf ―ya sea de forma predeterminada, como los que ya hemos mencionado, o mediante un complemento de otro proveedor.

## Protobuf vs. JSON: comparativa de ambos formatos

Cuando desarrolló Protocol Buffers, Google pretendía convertirlo en una alternativa a XML (del inglés *extensible markup language*, o lenguaje de marcado extensible). Lo cierto es que logró superarlo de muchas maneras: **estructurar los datos con Protobuf** no solo tiende a ser más fácil, sino que también garantiza obtener una estructura de datos entre tres y diez veces más pequeña y entre 20 y 100 veces más rápida que una estructura XML comparable, según afirma la propia compañía.

Protocol Buffers también suele compararse con el lenguaje de marcado JSON (JavaScript Object Notation) de JavaScript, aunque cabe mencionar que ambas tecnologías fueron diseñadas con objetivos diferentes: **JSON** es un **formato de texto sencillo** basado en JavaScript para intercambiar mensajes, siendo compatible con prácticamente todos los lenguajes de programación habituales. La funcionalidad de **Protobuf** abarca más que el formato de texto, porque esta tecnología de Google también ofrece varias reglas y herramientas para **definir e intercambiar los mensajes**. Además, Protobuf también supera a JSON en términos de rendimiento si analizamos el envío de los mensajes en general. En cualquier caso, ambos sistemas de estructuración tienen sus ventajas e inconvenientes, como verás en la siguiente tabla comparativa:

<table>
  <thead>
    <tr>
      <th></th>
      <th>Protobuf</th>
      <th>JSON</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Desarrollador</td>
      <td>Google</td>
      <td>Douglas Crockford</td>
    </tr>
    <tr>
      <td>Función</td>
      <td>Formato de marcado para datos estructurados (almacenamiento y transmisión) y biblioteca</td>
      <td>Formato de marcado para datos estructurados (almacenamiento y transmisión)</td>
    </tr>
    <tr>
      <td>Formato binario</td>
      <td>Sí</td>
      <td>No</td>
    </tr>
    <tr>
      <td>Estandarización</td>
      <td>No</td>
      <td>Sí</td>
    </tr>
    <tr>
      <td>Legible para el ser humano</td>
      <td>En parte</td>
      <td>Sí</td>
    </tr>
    <tr>
      <td>Comunidad/documentación</td>
      <td>Comunidad pequeña; manuales en línea extensibles</td>
      <td>Comunidad enorme, buena documentación oficial y diversos tutoriales en línea, etc.</td>
    </tr>
  </tbody>
</table>

Como habrás deducido, si necesitas un formato de serialización bien documentado que almacene y transfiera los datos estructurados de forma legible para el ser humano, deberás **recurrir a JSON** en lugar de Protocol Buffers, especialmente en los casos en que la parte del lado del servidor de la aplicación esté escrita en JavaScript y una gran parte de los datos sea procesada directamente por los navegadores de manera predeterminada. Sin embargo, cuando haya que favorecer la flexibilidad y el rendimiento de la estructura de los datos, Protobuf probablemente 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 diferencia en muchos proyectos de software, pero, como suele ser el caso, primero conviene conocer y saber aplicar las **características especiales y** los **trucos sintácticos** de esta tecnología de serialización. En el tutorial que figura a continuación, te enseñaremos a dar tus primeros pasos con Protobuf y podrás hacerte una idea de cómo se estructura la sintaxis y el intercambio de mensajes en este sistema: desde la definición de tu propio formato mediante un archivo *.proto* hasta la compilación de las estructuras de Protocol Buffers. Como ejemplo, te proponemos una aplicación sencilla: una **agenda de contactos** en **Java**, que puede leer los datos de contacto de un archivo y escribirlos en otro. A cada registro de la agenda se le asignan los parámetros “nombre”, “ID”, “dirección de correo electrónico” y “número de teléfono”.

### Definir nuestro propio formato de datos en el archivo .proto

En primer lugar, debes describir todas las estructuras de datos que desees implementar con Protocol Buffers en el archivo *.proto*, el archivo de configuración estándar de este formato de serialización. Para cada estructura que quieras serializar en este archivo ―es decir, introducir siguiendo una estructura― no tienes más que añadir un mensaje (en inglés, *message*). Después, debes especificar los **nombres** y **tipos** para cada campo de este mensaje y añadir el modificador o modificadores que quieras. Es obligatorio asignar un modificador a cada campo.

Para nuestra **agenda de contactos en Java**, esta podría ser una **posible asignación de las estructuras de datos** en el archivo *.proto*:

```none
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 especifica la correspondiente versión de Protobuf, en este caso, [proto3](https://developers.google.com/protocol-buffers/docs/proto3 "Guía oficial de proto3 de Google"), seguida de la descripción del paquete de software cuyos datos se desea estructurar, que siempre incluye un nombre único (aquí, *tutorial*). En nuestro ejemplo de código, se añaden también las **dos opciones específicas 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 continuación, figuran los mensajes de Protobuf, que pueden estar compuestos por un número ilimitado de campos. Entre ellos, disponemos 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 mencionado, a cada campo se le debe asignar al menos uno de los siguientes tres modificadores:

- ***required***: indica que es obligatorio asignar un valor al campo. En caso contrario, el estado del mensaje es *uninitialized*, es decir, sin inicializar o sin enviar.
- ***optional***: en los campos opcionales, 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 predeterminado *HOME* (número de teléfono fijo) para el tipo de número de teléfono.
- ***repeated***: los campos con este modificador pueden repetirse un número indefinido de veces (incluso ninguna).

En el [foro para desarrolladores de Google](https://developers.google.com/protocol-buffers/docs/proto "Google Developers: Language Guide"), encontrarás informació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 estructuras de datos en el archivo *.proto*, debes generar las clases necesarias para la lectura y la escritura de los mensajes de Protobuf. Para ello, aplica el **compilador de Protocol Buffers** (Protoc) al archivo de configuración. Si aún no lo has instalado, puedes descargar la versión actualizada en el [repositorio oficial de GitHub](https://github.com/protocolbuffers/protobuf/releases/ "github.com: “protocolbuffers/protobuf”"). Descomprime el archivo *.zip* en la carpeta que quieras y, a continuación, inicia el compilador (ubicado en la carpeta “bin”) haciendo doble clic.

---

### Nota

Asegúrate de descargar la **edición correcta** del compilador de Protobuf, ya que Protoc está disponible para arquitecturas de 32 y 64 bits (Windows, Linux o macOS.

---

Finalmente, debes especificar lo siguiente:

- **Directorio fuente** en el que se encuentra el código del programa (en nuestro ejemplo, la carpeta “SRC\_DIR”)
- **Directorio 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 disponibles para el resto de lenguajes compatibles). El comando de compilación completo se vería así:

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

---

### Consejo

Google proporciona un **tutorial detallado de Protobuf con Java**, que también explica cómo transferir mensajes a través de Protocol Buffers (lectura/escritura), en un [apartado dedicado en Google Developers](https://developers.google.com/protocol-buffers/docs/tutorials "Google Developers: tutoriales de Protobuf"), la página para desarrolladores de proyectos de software que ofrece el gigante informático. Allí también figuran las instrucciones para trabajar con el resto de lenguajes compatibles, como C++, Go o Python.

---


This is a markdown version of: [https://www.ionos.mx/digitalguide/paginas-web/desarrollo-web/protocol-buffers/](https://www.ionos.mx/digitalguide/paginas-web/desarrollo-web/protocol-buffers/) for AI/LLM consumption.