Habitualmente al hablar de APIs nuestro pensamiento se dirige al uso de HTTP y REST al ser la opción más popular y extendida.

Pero el aumento en la adopción de las arquitecturas orientadas a eventos, el uso de distintos proveedores cloud, así como la cantidad y heterogeneidad de productos dentro del stack tecnológico de los clientes, ha supuesto un aumento en la diversidad de los casos de uso.

Esto implica que, para ciertas casuísticas, se demanden una serie de necesidades a nivel de integración que no son cubiertas de forma óptima por las tradicionales soluciones basadas en APIs REST.

¿Qué es gRPC?

Una de las opciones que está adquiriendo fuerza es el uso de gRPC. gRPC es una implementación de llamadas a procedimiento remoto (RPC) diseñado originalmente por Google, de ahí su nombre: g (Google) + RPC.

Actualmente es un componente open source y su distribución la realiza la Cloud Native Computing Foundation y para cada nueva versión cambia el significado de la "g", hasta el punto en que incluso hicieron un README para enumerar todos sus significados.

Se emplea en comunicaciones cliente-servidor distribuidas por su eficiencia gracias a la ingeniería de procesos basada en RPC. Este mecanismo permite la comunicación de una forma tan sencilla como si se tratara de una comunicación local entre procesos de una misma máquina.

En los últimos años está ganando bastante popularidad como una alternativa para cierto tipo de integraciones, ¿a qué se debe su adopción? Pues algunas de las razones son:

  • Su sencillez. Son una simple llamada a una función, por lo que los desarrolladores no tienen que preocuparse de la documentación y no requiere mucho código.
  • Su flexibilidad, ya que permite trabajar con múltiples lenguajes.
  • Su rendimiento, lo que las convierte en una alternativa muy atractiva para llamadas entre servicios en lugar de realizar las tradicionales llamadas HTTP.

Un ejemplo claro de su expansión es que una de las herramientas más utilizadas en este ámbito como Postman ha incluido soporte para GRPC recientemente.

¿Cómo funciona gRPC?

La arquitectura de RPC se basa en los siguientes pasos:

Distintos pasos de la arquitectura de RPC para cliente y servidor.
  1. La aplicación cliente realiza una llamada de procedimiento local al stub con los parámetros necesarios para la ejecución de la operativa en el servidor.
  2. El stub del cliente serializa los parámetros a través de un proceso denominado clasificación y llama a la librería run-time del cliente con los datos serializados.
  3. La librería run-time del cliente reenvía la solicitud al run-time del servidor a través de la capa de transporte.
  4. La librería run-time del servidor llama al Stub del servidor pasándole la petición recibida.
  5. El stub del servidor es el encargado de deserializar los datos y enviarlos al controlador o procedimiento real registrado para esta petición.
  6. A continuación el servidor ejecuta la solicitud y retorna la respuesta al Stub del servidor.
  7. El stub del servidor serializa el objeto de respuesta y llama a la librería run-time del servidor con la respuesta serializada.
  8. La librería run-time del servidor devuelve al cliente la respuesta a través de la capa de transporte a través de la librería run-time del cliente.
  9. La biblioteca de tiempo de ejecución del cliente deserializa la respuesta al objeto de solicitud definido en el código auxiliar del cliente.
  10. Finalmente, la respuesta se devuelve al método del destinatario.

Muchas de las complejidades de este proceso están ocultas a los desarrolladores como el stub y la comunicación de la capa de transporte, lo cual simplifica su implementación.

RPC vs GRPC

Y ¿qué diferencia gRPC de RCP? Pues introduce dos mejoras sustanciales que son:

  • El uso de HTTP/2 para el envío de datos a través de la capa de transporte.
  • La utilización de Protocol buffers para la gestión de la estructura y distribución de los datos.

1 HTTP/2

Una de las razones por las que gRPC funciona tan bien es el uso de HTTP/2, creado por Google en 2015, el mismo año que gRPC.

HTTP (Hypertext Transfer Protocol) es un protocolo de comunicación que permite la transferencia de información en internet. La versión más conocida es la HTTP/1.1, pero tiene algunas limitaciones. La más importante es que necesita una conexión TCP/IP (capa de transporte dentro del protocolo HTTP) por cada elemento que quiere obtener. Para superar esta limitación surge HTTP/2, que aunque conserva la misma semántica que la versión HTTP/1.1 presenta las siguientes mejoras:

  • Multiplexación

Mientras que con HTTP/1.1 para cargar cualquier elemento se requiere múltiples conexiones TCP, con HTTP/2 se utiliza una única conexión, a través de la cual se pueden enviar varias peticiones y recibir varias respuestas de forma simultánea, ya que la comunicación es bidireccional mejorando la eficiencia considerablemente.

Y como una imagen vale más que mil palabras, aquí tenemos un ejemplo en el que se ve la diferencia entre usar HTTP/1.1 y HTTP/2 al cargar varias imágenes.

  • Compresión de cabeceras

En HTTP/1.1 cada petición que se envía tiene un bloque formado por las cabeceras para indicar cierto comportamiento entre el cliente y el servidor. En HTTP/2 todas esas cabeceras se empaquetan en un único bloque comprimido de forma que se obtienen mejores tiempos de respuesta. Además la compresión se realiza mediante el algoritmo HPACK el cual se encarga de eliminar campos redundantes y prevenir posibles vulnerabilidades.

  • Server push

HTTP/2 permite que el servidor envíe mensajes antes de que el cliente los solicite. El funcionamiento es simple, cuando el servidor recibe una petición este retorna la respuesta asociada y en caso de que estime que puede necesitar algún recurso adicional también lo envía. Por ejemplo, al retornar una página HTML también puede enviar los archivos CSS, las imágenes o las fuentes antes de que el navegador los solicite, evitando el envío de solicitudes adicionales y mejorando el rendimiento.

  • Priorización de flujos

A la hora de transmitir información algunos componentes son más importantes que otros. HTTP/2 permite asignar diferente prioridad dentro de mensajes HTTP. Cada mensaje HTTP es dividido en fragmentos y se puede asignar una prioridad a cada uno de ellos gracias a lo cual se controla mejor el orden y el retardo de los elementos.

  • Formato binario en lugar de texto

HTTP/2 envía y recibe la información de forma binaria mientras que HTTP/1.1 lo realiza en texto. La ventaja de usar un protocolo binario es la eficiencia tanto en su transporte al estar la información más compactada, como en su interpretación, ya

2 Protocol Buffers - Protobuf

GRPC utiliza Protobuf para:

  • La serialización de las estructuras de datos, es decir, es el formato subyacente para el intercambio de mensajes.
  • Describir la interfaz de comunicación, es decir, actúa como el contrato intermediario que permite que el cliente y el servidor se entiendan.

Esta información se define en un fichero .proto que contiene:

  • Las definiciones de las estructuras de los mensajes con los tipos de datos y parámetros intercambiados.
  • Los servicios que definen los procedimientos o funciones que se realizan.

Un ejemplo sencillo sería el siguiente:


syntax = "proto3";
package com.book;

message Book {
    int64 isbn = 1;
    string title = 2;
    string author = 3;
}

message GetBookRequest {
    int64 isbn = 1;
}

message GetBookViaAuthor {
    string author = 1;
}

service BookService {
    rpc GetBook (GetBookRequest) returns (Book) {}
    rpc GetBooksViaAuthor (GetBookViaAuthor) returns (stream Book) {}
    rpc GetGreatestBook (stream GetBookRequest) returns (Book) {}
    rpc GetBooks (stream GetBookRequest) returns (stream Book) {}
}

Tiene como ventajas que:

  • Describe la interfaz de manera independiente de cualquier lenguaje, es decir, no está vinculado a un lenguaje de programación específico.
  • La serialización es binaria que es más rápida que una serialización de texto como sería el caso del uso de JSON en APIs REST.
  • A diferencia de JSON, es posible definir el tipado de los campos y las validaciones de los mismos en el fichero .proto.

¿Qué nos aporta gRPC?

Una vez detallada la arquitectura básica de gRPC y cómo funciona, veremos qué es capaz de hacer:

1 Streaming

Gracias a la multiplexación de HTTP/2 mencionada anteriormente es posible procesar información en Streaming de diferentes formas:

Diferentes formas de streaming del cliente al servidor y del servidor al cliente.
  • Unaria: el cliente envía una única solicitud y el servidor devuelve una única respuesta.
  • Streaming del servidor: el cliente envía una única solicitud y el servidor puede retornar múltiples respuestas, es decir, un flujo de respuesta.
  • Streaming del cliente: donde el cliente envía múltiples peticiones y el servidor devuelve una única respuesta.
  • Streaming bidireccional: en la que tanto el cliente como el servidor envían mensajes entre sí de forma simultánea, es decir, sin esperar respuesta del otro lado.

Si quieres ver un ejemplo de la implementación de un servicio de cada uno de los tipos de streaming aquí tienes el post sobre el paso a paso con Java Spring Boot y Postman.

2 Interceptores

gRPC permite capturar los mensajes tanto de solicitud como de respuesta y modificarlos a través de interceptores.

Estos interceptores se asemejan a lo que podría ser un middleware en el mundo HTTP de una API Rest ya que permite:

  • Modificar la solicitud o respuesta antes de entregarla al destinatario, por ejemplo para incluir información obligatoria antes de llegar al cliente o servidor.
  • Manipular cada llamada para agregar información adicional y rastrear el tiempo de respuesta.

3 Balanceo de carga

Habitualmente el balanceo de carga se realiza a nivel de proxy, por ejemplo mediante un NGINX, pero gRCP proporciona un mecanismo de balanceo de carga tanto del lado del cliente como del lado del servidor que puede utilizarse con relativa facilidad.

4 Cancelación de llamada

Los clientes de gRPC pueden cancelar una petición cuando yo no necesitan la respuesta. Esto es especialmente útil en el lado del servidor cuando está en modo Streaming ya que gracias a un patrón que permite observar si las solicitudes se cancelan puede detectar dicha cancelación y anular esas peticiones.

5 ¿Cómo se trabaja con Protobuf y GRPC?

Los pasos serían los siguientes:

  • Definición del contrato del servicio. Se establecen los servicios, parámetros de petición y respuesta a través de la definición de un fichero .proto
  • Compilación del fichero mediante el uso de unos compiladores especiales llamados protoc, partiendo del fichero .proto definido en el paso anterior, se compila automáticamente los datos.
  • Generación del código GRPC. Se genera el código destino en lenguajes como: Java, C ++, Python, Go, Dart, Objective-C, Ruby
  • Implementación del stub del servidor: se realiza la implementación del servicio del lado del servidor, es decir, se programan los métodos y llamadas con la lógica necesaria para procesar la Proto Request y retornar la Proto Response.
  • Implementación del stub del cliente: se realiza la implementación del cliente con la llamada al servicio.
Implementación del cliente con la llamada al servicio.

Ventajas

Entre las ventajas que presenta el uso de gRPC tenemos las siguientes:

  1. La tecnología es fácil de utilizar:
  • La estructura en capas fuertemente estandarizada del framework gRPC permite reducir el esfuerzo de programación. De esta forma, los desarrolladores pueden centrarse en la implementación de la lógica de negocio.
  • Generación de código. Gracias a la utilización de Protobuf para la definición de los formatos del mensaje como de los métodos se pueden producir los esqueletos de código tanto del cliente como del servidor disminuyendo el tiempo de desarrollo.
  1. La flexibilidad:
  • Gracias al uso de Protocols Buffers y sus compiladores es posible la comunicación independientemente del lenguaje de programación y del sistema operativo, es decir, elimina esas “fronteras”.
  1. La eficiencia a nivel de comunicación gracias a HTTP/2:
  • Debido a la multiplexación y el streaming bidireccional así como a la compresión de los encabezados se reduce de manera notable el volumen de datos y la cantidad de solicitudes y respuestas.
  • Además se reduce la latencia de red ya que permite conexiones más rápidas y duraderas disminuyendo el tiempo que suponía la configuración de las solicitudes HTTP/1.x individuales.
  1. El uso de seguridad:
  • gRPC cuenta con una autenticación integrada y fomenta el uso de SSL/TLS para la autenticación y la codificación de los mensajes.

Desventajas

Por otro lado, también presenta varias desventajas que obstaculizan enormemente su adopción de forma masiva:

  1. Uso de un formato no legible. Los mensajes en Protobuf no se pueden leer directamente, se necesitan herramientas adicionales para analizar el tráfico de datos pero sobre todo para debuggear errores.
  2. La falta de madurez respecto otras tecnologías como GraphQL o REST que se traduce en:
  • Falta de herramientas para desarrolladores sobre HTTP/2 y Protobuf ya que actualmente las herramientas que solo admiten HTTP/1 no son útiles en el proceso de desarrollo de gRPC.
  • Ausencia de buenas prácticas, hay poca documentación y detalle sobre casos de éxito reales que indiquen qué está funcionando y cómo utilizar gRPC de forma productiva.
  • Soporte limitado en navegadores debido al uso de HTTP/2. Además es necesario el uso de un proxy para llamar a un servicio de gRCP, no es posible llamarlo directamente desde un navegador.
  1. La curva de aprendizaje es pronunciada en comparación con REST y GraphQL. Esto limita su adopción y también dificulta encontrar desarrolladores que conozcan la tecnología. Una vez pasada la barrera de familiarizarse con la tecnología su uso es sencillo.
  2. Ausencia de manejo de errores de forma consistente. De momento gRPC adolece de una forma estandarizada para la detección de errores en los distintos lenguajes de programación, aunque maneja los conceptos de código y mensaje de estado no está pensado para incluir en el mensaje de respuesta los errores que se han producido. Es un punto sobre el que se está trabajando y existe una guía que puede servir de ayuda en este ámbito.
  3. Por último, la falta de compatibilidad con multicasting.

¿Qué es mejor GRPC o REST?

La respuesta correcta, como en la mayoría de estas comparativas, es que depende del caso de uso en concreto. En ciertas ocasiones la solución que mejor se adapta puede ser GRPC y en otros casos REST.

Para tomar la decisión más acertada conviene tener en cuenta las diferencias fundamentales entre ambas opciones:

Cuadro con las principales diferencias entre gRPC y REST.

Escenarios para usar gRPC

Teniendo en cuenta los puntos anteriores hay ciertos escenarios en los que gRPC puede ser la solución más adecuada:

  • En servicios de comunicación punto a punto en tiempo real. En aquellas situaciones en las que se requiera una comunicación punto a punto en tiempo real gRPC es la opción más acertada gracias a HTTP/2. Un ejemplo típico de este tipo de soluciones son el IoT y la domótica.
  • En soluciones cuyo objetivo sea una comunicación eficiente. En escenarios que necesiten una comunicación eficiente entre procesos que busquen una latencia baja y un flujo elevado de datos y mensajes puede ser una opción a considerar. Un ejemplo de este tipo de soluciones puede ser la conexión entre sí de microservicios.
  • En entornos multilingües, es decir, cuando haya multitud de lenguajes de programación dentro del entorno de desarrollo del proyecto.
  • En soluciones de integración: Gracias a la velocidad, la eficiencia el carácter multilingüe de gRPC puede ser una buena alternativa en escenarios que requieren la integración y comunicación con aplicaciones del ámbito móvil, sobre todo en tramos de procesamiento distribuido de datos, ya que conecta los dispositivos, las aplicaciones incluso servicios de proveedor externos con servicios backend. Un ejemplo de este tipo son las APIs expuestas a través de gRPC en Google.

Conclusiones

En resumen, gRPC no es ni una evolución ni un reemplazo para REST, solo es una alternativa a considerar cuando se diseña e implementa una API.

Su uso es adecuado en proyectos para comunicaciones internas cuyos requisitos están alineados con las ventajas del uso de la propia tecnología: una gran escalabilidad, respuesta optimizada y baja latencia.

En caso de querer realizar un proyecto en gRCP o conocer más en profundidad esta tecnología un posible “welcome pack” sería el siguiente:

  • Guías oficiales de gRPC y Protocols Buffers a través de tutoriales y ejemplos de uso.
  • El grupo de Google con la comunidad para poder trasladar las dudas y ver cuestiones de otros desarrolladores.
  • Algunas herramientas incluidas en el ecosistema de gRCP en GitHub.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.