logo cosasdedevs
Cómo instalar Protobuf (Protocol Buffers) en Windows sin morir en el intento

Cómo instalar Protobuf (Protocol Buffers) en Windows sin morir en el intento



My Profile
Ene 27, 2021

La semana pasada me tocó instalar y trabajar con Protobuf y no os voy a engañar, fue un puto infierno. Me costó instalarlo y luego tuve mil problemas para hacerlo funcionar 😡. Al final era por un problema de versiones😅.

Como no quiero que paséis por el sufrimiento y sobre todo mala leche que pasé yo hasta ponerlo todo en funcionamiento, he preparado un tutorial para dejarlo todo explicado paso a paso.

Pero antes de nada...

¿Qué es Protobuf (Protocol Buffers)?

Es un método para serializar estructuras de datos. Es útil en el desarrollo de programas que necesitan comunicarse entre sí a través de una red o para almacenar datos. La diferencia entre otros métodos como XML o JSON es que la serialización de datos se genera de forma más pequeña, rápida y sencilla. Esto es útil en procesos que comunicarse entre sí a través de la red para ahorrar tiempo y costes gracias a su reducido tamaño. Para utilizarlo, solo tienes que definir la estructura con los datos que quieres almacenar y con Protobuf generaremos las clases para posteriormente serializar nuestros objetos.

Protobuf actualmente tiene soporte para los siguientes lenguajes:
C++
Java
Python
PHP
Go
C#
Javascript

Instalar Protobuf con Conda

Para instalar Protobuf, usaremos conda. Para el que no lo sepa, conda es un sistema de gestión de paquetes de código abierto. Esta herramienta nos ayudará a instalar fácilmente Protobuf desde la terminal. Además configurará el Path para que podamos usar el comando de Protobuf en cualquier parte sin tener que añadir toda la ruta. Vamos, que todo son ventajas 😁.

Instalar Conda en Windows

Para instalar conda, solo debemos ir al siguiente enlace https://docs.conda.io/projects/conda/en/latest/user-guide/install/windows.html. Ahí nos aparecerán dos opciones de descarga, miniconda y anaconda. Nosotros descargaremos miniconda.

Cuando abramos el instalador, nos aparecerán las típicas opciones para aceptar los términos y condiciones, donde instalarlo, etc, vamos el típico siguiente, siguiente y siguiente excepto en un paso

Llegará un punto en el que nos preguntará si queremos añadir conda al path del entorno de variables. Ahí debemos marcar el check y dar a instalar. Esto hará que podamos utilizar el comando de conda en la terminal desde cualquier parte.

Una vez tengamos instalado conda, abrimos la terminal y escribimos el siguiente comando para instalar Protobuf:

conda install -c anaconda protobuf=3.13

Nota: Aunque actualmente existe la versión 3.14.0, esta tiene un error con PHP que lanza el siguiente mensaje cuando intentamos crear un objeto con las clases que nos genera Protobuf:

Error occurred during parsing: Fail to push limit.

Te recomiendo que no instales esa versión si vas a trabajar con PHP. Si cuando leas esto, ya existe una versión posterior, te recomiendo que la pruebes y nos dejes un comentario para avisar si sigue el problema o lo han solucionado 🤗.

Si todo ha ido bien, tendremos Protobuf instalado y funcionando en nuestra terminal así que ahora vamos a explicar como utilizarlo con PHP.

Ejemplo de Protobuf con PHP

Para intentar dejarlo lo más claro posible, vamos a crear un proyecto de ejemplo. Para ello, creamos una carpeta donde guardar el proyecto y dentro de esta, añadimos un archivo llamado search.proto. En este archivo, definiremos la estructura de datos que queremos almacenar así que abrimos el archivo y añadimos la siguiente información:

syntax = "proto3";

package app.proto;

message Search {
    string query = 1;
    int32 page_number = 2;
    int32 result_per_page = 3;
}

Lo primero que indicamos es la versión de la sintaxis, la última versión es la número tres que es la que utilizaremos. Además solo hay soporte en PHP para esta versión así que no hay nada más que hablar 🤷‍♂️.

La siguiente línea es el paquete. Esto lo que hará, es que cuando lancemos el comando para nuestras clases, genere esa estructura de carpetas para contener la clase que utilizaremos para la serialización.

El último paso es definir el mensaje. Le daremos un nombre (en este caso Search) y añadiremos los campos que queremos almacenar en el mensaje. En este caso, quiero guardar un campo query que será de tipo string y un page_number y result_per_page que serán de tipo int32. Como se muestra en el ejemplo, cada campo de la definición de mensaje tiene un número único. Estos números de campo se utilizan para posteriormente identificarlos en el binario que genera. Se recomienda utilizar los números del 1 al 15 para los mensajes más utilizados, ya que estos solo ocupan un byte.

Este es un ejemplo muy sencillo, pero se pueden hacer muchas más cosas. Para profundizar sobre la sintaxis, os dejo el enlace a la documentación.

Ahora, vamos a generar las clases de forma automática, para ello, abrimos la terminal y vamos a la raíz de nuestro proyecto donde tenemos el archivo search.proto. Ahí debemos lanzar el siguiente comando:

protoc --proto_path=. --php_out=. search.proto

El atributo --proto_path, indica donde está la ruta del proyecto, en nuestro caso ponemos el punto (.), ya que nos hemos movido a ese directorio.

El atributo --php_out, indica que queremos que genere las clases en el lenguaje PHP y que estas, estén alojadas en el directorio actual. Aun así, como indicamos en el archivo search.proto el paquete app.proto, el comando generará la estructura de carpetas App/Proto.

Por último, le decimos la estructura de datos sobre la que debe generar las clases que en este caso es el archivo search.proto.

Ahora que ya tenemos las clases, vamos a crear el archivo composer.json para instalar las dependencias y facilitarnos el proceso de carga de librerías. Si no tienes muy claro como trabajar con composer, te dejo este tutorial donde explico como usarlo paso a paso.

{
    "name": "alber/protobufxphp",
    "description": "Tutorial para utilizar protobuf con php",
    "type": "project",
    "license": "MIT",
    "authors": [
        {
            "name": "Alberto",
            "email": "alberto@cosasdedevs.com"
        }
    ],
    "minimum-stability": "stable",
    "require": {
        "google/protobuf": "^3.14"
    },
    "autoload": {
        "psr-4": {
            "App\\": "App/"
        }
    }
}

Como podéis observar, hemos añadido el paquete google/protobuf de PHP. Este paquete lo necesitamos porque lo usan las clases que generamos anteriormente con el comando protoc. En este caso, la versión 3.14 sí que funciona perfectamente 🤷‍♂️.

El siguiente paso es instalar los paquetes. Para ello, lanzamos el siguiente comando:

composer install

Una vez instalados los paquetes, es hora de crear un mensaje. Para ello, creamos un archivo llamado index.php y añadimos el siguiente código:

<?php

require __DIR__ . '/vendor/autoload.php';
include 'GPBMetadata/Search.php';
use App\Proto\Search;

echo 'Create message' . PHP_EOL;

$from = new Search();
$from->setQuery('This is a test');
$from->setPageNumber(1);
$from->setResultPerPage(10);

$to = new Search();

$data = $from->serializeToString();

try {
    $to->mergeFromString($data);
    echo 'Read query: ' . $to->getQuery() . PHP_EOL;
} catch (Exception $e) {
    echo $e->getMessage() . PHP_EOL;
}

En este archivo, cargamos los paquetes y después importamos los archivos generados. Lo siguiente que hacemos es crear un mensaje de tipo Search que es nuestro Protobuf donde podremos setear los datos de nuestro mensaje utilizando el método set más el nombre de nuestro campo en formato camelCase.

Después, serializamos los datos con el método serializeToString() que es el que se encargará de generar el binario.

Por último, generamos otro objeto llamado $to también de la clase Search() que será el que leerá el binario y lo convertirá a un formato legible. Para ello, utilizamos el método mergeFromString() y le pasamos el binario. Ahora con los métodos get más el nombre de nuestro campo en formato camelCase, podremos acceder a los datos del mensaje como veis en el ejemplo.

Cualquier duda la podéis dejar en la caja de comentarios y como siempre os dejo el enlace al proyecto.

Espero que este post te ayude y como siempre, te recomiendo seguirme en Twitter para estar al tanto de los nuevo contenido. Ahora también puedes seguirme en Instagram donde estoy subiendo tips, tutoriales en vídeo e información sobre herramientas para developers.

Por último os dejo mi guía para aprender a trabajar con APIs donde explico todo el funcionamiento de una API, el protocolo HTTP y veremos como construir una API con arquitectura REST.

Nos leemos 👋.

3176 vistas

🐍 Sígueme en Twitter

Si te gusta el contenido que subo y no quieres perderte nada, sígueme en Twitter y te avisaré cada vez que cree contenido nuevo 💪
Luego ¡Te sigo!

Nos tomamos en serio tu privacidad

Utilizamos cookies propias y de terceros para recopilar y analizar datos sobre la interacción de los usuarios con cosasdedevs.com. Ver política de cookies.