gRPC es un mecanismo moderno de invocación de métodos remotos (RPC) entre procesos/sistemas/servicios, desarrollado por Google y hoy día es mantenido por la CNCF (Cloud Native Computing Foundation), de código abierto y entre sus características encontramos:
- El transporte se realiza sobre HTTP/2.
- hace uso de Protobuf como interfaz de descripción de lenguaje: Protobuff es neutral y se usa para definir los mensajes enviados y recibidos por un servicio gRPC.
- Provee autenticación, streaming bidireccional y control de flujo.
- Permite generar clientes multiplataformas.
- Su uso más común es entre microservicios.
Entre sus puntos fuertes encontramos :
- Desempeño: los mensajes se serializan con Protobuf, lo cual es muy veloz tanto en cliente como en servidor, generando cargas útiles (payloads) pequeñas, que es un aspecto importante cuando el ancho de banda es limitado(p.ej: mobile apps). Además de multiplexación de varias llamadas sobre una única conexión TCP.
- Todos los frameworks para gRPC, proveen soporte para generación de código(partiendo del archivo .proto).
- gRPC provee soporte para streaming a través de HTTP/2.
- gRPC permite a los clientes especificar cuánto estan dispuestos a esperar para que complete la solicitud, el tiempo límite se envía al servidor y este decide que acción tomar si se excede el tiempo.
Por otro lado, entre sus debilidades:
Soporte navegador limitado (de momento): los navegadores no proveen el nivel de control necesario para solicitudes que un cliente gRPC requiere (por ejemplo, no hay forma de forzar el uso de HTTP/2 y de haberlo, las tramas HTTP/2 son inaccesibles al navegador).
No es legible por humanos: a diferencia de REST, los mensajes gRPC son codificados con Protobuf.
Flujo de trabajo
Para empezar a usar gRPC, debemos tener en cuenta los siguientes pasos :
- Definir un contrato y mensajes : gRPC usa una aproximación basada en contratos para desarrollar Apis y los contratos describen los servicios a exponer con parametros y respuestas.
- Generar el código RPC a partir de los archivos .proto, que como se mencionó anteriormente, Protobuff es usado como el IDL para gRPC.
- Implementar el código servidor.
- Generar el cliente (stub).
Manos a la Obra
En esta guía construiremos un servidor y un cliente con netcore 3.1 y VSCode. Empecemos por el Server, para ello creamos una aplicación de consola con dotnet (de tipo grpc)
dotnet new grpc -n MyServer
Paso siguiente, ir a la carpeta MyServer y añadir los siguientes paquetes a la solución.
dotnet add package Google.Protobuf dotnet add package Grpc.Tools dotnet add package Grpc.AspNetCore
Podrás notar que en la jerarquía de carpetas del proyecto tienes una carpeta llamada Protos en el cual se mantienen los archivos .proto, en este caso greet.proto y que tiene las definiciones de los mensajes e interfaces de servicios.
Este archivo y todos los .proto se incluyen en el .csproj de la solución así:
Es de anotar el valor del atributo GrpcServices=”Server”, en este caso está indicando que este es el servidor, cuando construyamos el cliente este valor cambia a “Client” (Usaremos el mismo archivo .proto para definir tanto cliente como servidor).
Para nuestro ejercicio crearemos un nuevo archivo .proto, definiremos nuestros mensajes y servicios y lo añadimos al .csproj.
syntax = “proto3” debe ser la primera linea del archivo, aquí se especifica que estamos usando la sintaxis proto3 y si no se especifica, el compilador asume la versión proto2.
Como pueden observar se trata de un simple servicio para resolver una división, no es muy elaborado y entiendo que se pueden definir mejor los tipos de datos, pero se trata de simpleza.
Cada campo en la definición del mensaje tiene un número único y su función es identificar los campos en el formato binario de mensaje (message binary format) y no debe ser cambiado una vez el tipo de mensaje esta en uso.
Continuamos dándole implementación al contrato (recuerden que debemos compilar el proyecto para poder generar las clases bases a implementar), que en este caso expone un único método llamado Divide el cual recibe como parámetro un mensaje de tipo DivisionRequest y retorna un mensaje de tipo DivisionResponse. Estos mensajes se deben “traducir” a tipos usados en C# y estan disponibles una vez compiles el proyecto.
OperacionService hereda del tipo OperacionMatematicaBase, el cual es generado a partir del servicio OperacionMatematica del archivo .proto.
Debemos decirle al middleware de la aplicación que hay un servicio a publicar (en el método Configure de la clase Startup.cs) via IEndpointRouteBuilder.MapGrpcService<T>.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGrpcService<OperacionService>(); endpoints.MapGet(“/”, async context => { await context.Response.WriteAsync(“Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909”); }); }); }
Podemos verificar que nuestro servicio quedó bien construido, ejecutemos los comandos:
dotnet build
dotnet run
y esta es la salida
Ya constatamos que nuestro servicio funciona, ahora pasemos al cliente. Para ello podemos generar otro proyecto con algunas modificaciones y vamos a usar el archivo .proto generado en el servidor.
dotnet new console -n MyClient
Ingresamos a la carpeta MyClient e instalamos los siguientes paquetes:
dotnet add package Google.Protobuf
dotnet add package Grpc.Tools
dotnet add package Grpc.AspNetCore
En este punto tomamos el .proto del proyecto MyServer, creamos una carpeta llamada Protos en la ubicación del proyecto MyClient y allí colocamos el archivo. Luego modificamos el archivo .csproj de la solución y añadimos la siguiente sección dentro de <Project>
<ItemGroup>
<Protobuf Include=”Protos\Test.proto” GrpcServices=”Client” />
</ItemGroup>
En este proyecto el atributo GrpcServices tiene valor “Client” (al tratarse de un cliente que estamos construyendo).
Construye el proyecto para generar el código cliente con :
dotnet build
Ahora creemos un cliente para consumir el servicio :
Ahora a probar!! arranquemos MyServer y luego ejecutamos MyClient
gRPC esta tomando relevancia para el desarrollo de microservicios, comunicacion en tiempo real punto a punto, entornos políglotas, comunicación interprocesos (IPC), en fín, vale la pena aprenderlo independientemente del stack tecnológico de tu preferencia. El ejercicio completo está en https://github.com/cheoalfredo/gRPC-Demo.
¿Te gustó? ¿vamos por más? Déjame conocer tu opinión.
Te invito a seguirme en mi blog https://cheoalfredo.medium.com/