Cómo crear una API segura con gRPC
Vitalis Ogbonna
25 de agosto de 2022
0 minutos de lecturaUna llamada a procedimiento remoto de Google (gRPC) es la versión de código abierto de Google del framework de llamadas a procedimientos remotos (RPC). Es un protocolo de comunicación que aprovecha las tecnologías HTTP/2 y Protocol Buffers (protobuf). gRPC permite que un cliente o servidor remoto se comunique con otro servidor con solo llamar a la función del servidor receptor como si fuera local. Esto facilita mucho la comunicación y la transferencia de grandes conjuntos de datos entre el cliente y el servidor en sistemas distribuidos.
Al igual que otros sistemas RPC, gRPC define un servicio. Especifica sus métodos y tipos de retorno mediante protobuf —un protocolo de Google para la serialización y deserialización—, lo que facilita la definición de servicios y la generación automática de bibliotecas cliente. gRPC usa este protocolo, actualmente en la versión 3, como lenguaje de definición de interfaces y conjunto de herramientas de serialización.
Para la mayoría de las aplicaciones modernas, gRPC es una excelente opción gracias a su compatibilidad con todo tipo de datos. Es ideal para grandes volúmenes de datos, como los datos de streaming, y puede ser excesivo para aplicaciones sencillas en las que la transferencia de grandes cantidades de datos no es una prioridad.
En este artículo aprenderás a usar gRPC mediante la comunicación entre un cliente y un servidor de dos aplicaciones Node.js. También destacaremos algunas medidas de seguridad para usar gRPC como mecanismo de comunicación en tus servicios.
Requisitos previos del tutorial
Para este tutorial, debes tener OpenSSL y Node.js (versión 4.0 o posterior) instalados en tu PC. Es fundamental tener conocimientos básicos de Node.js y JavaScript. También debes asegurarte de que tu entorno de trabajo tenga privilegios de administrador.
Configurar el proyecto de Node.js
Primero, para establecer la estructura de carpetas de la aplicación, crea una carpeta llamada event-app-node-grpc e inicializa un proyecto de Node.js con npm. Para ello, escribe los siguientes comandos:
Una vez inicializada la aplicación, crea la siguiente estructura de carpetas. Puedes consultar en GitHub el código completo que usamos en este tutorial:
Instalar paquetes
En la terminal, ve al directorio raíz de la aplicación. Instala los siguientes paquetes con el comando npm install, como se muestra en el siguiente fragmento de código:
Veamos los paquetes que acabas de instalar en el fragmento de código anterior:
Expresses el servidor HTTP de tu aplicación.@grpc/grpc-jses una biblioteca de gRPC para Node.js. Permite crear un servicio gRPC en el entorno de ejecución de Node.js.@grpc/proto-loaderes un paquete necesario para cargar archivos protobuf y usarlos con gRPC. Usa la versión 3 del paqueteprotobuf.js.
Después de instalar los paquetes anteriores, abre el archivo package.json y agrega las siguientes configuraciones a las etiquetas scripts, como se muestra en el fragmento de código:
Las configuraciones adicionales del fragmento de código anterior corresponden a la configuración del entorno de ejecución de la aplicación y a la generación del certificado SSL. Una vez agregadas, el archivo package.json actualizado debería verse como el siguiente fragmento de código:
El fragmento de código anterior muestra el archivo package.json actualizado después de agregar a la etiqueta scripts los comandos para configurar el entorno de ejecución de la aplicación y generar el certificado SSL.
Definir el Protocol Buffer
En este tutorial se muestra cómo usar gRPC en una aplicación sencilla de seguimiento de eventos. La aplicación de demostración recibe detalles de eventos y los guarda en una base de datos en memoria, y permite actualizar, consultar y eliminar los datos de los eventos.
En las aplicaciones gRPC, la interfaz del servicio y las cargas útiles necesarias se definen en un archivo protobuf para permitir la comunicación entre distintas aplicaciones. Los archivos protobuf tienen la extensión .proto, como se muestra en el esquema de configuración del proyecto.
Ahora, en el directorio raíz de la aplicación, crea un archivo events.proto y agrega el siguiente código. Puedes consultar como referencia el esquema de estructura del proyecto que definimos antes.
En los fragmentos de código de definición de proto anteriores, primero especificamos la versión de Protocol Buffer con la definición syntax = "proto3" y, después, definimos el servicio de protocolo.
Luego, en la descripción del servicio de eventos del protocolo, creamos un servicio llamado EventService. Después, creamos funciones rpc dentro de este servicio, junto con los parámetros necesarios y los valores de retorno esperados. Puedes definir tantos servicios como necesite tu aplicación, pero, para simplificar, definimos solo uno.
También definimos los tipos de datos para la función rpc en la definición de EventService y los valores de retorno mediante el sistema exclusivo de numeración de campos de gRPC. Este sistema especifica la cantidad de bytes que se usan durante la codificación. Consulta más detalles en la documentación oficial de protobuf.
Crear el servidor gRPC
Siguiendo la estructura de carpetas anterior, crea una carpeta server en el directorio raíz de la aplicación y, dentro de ella, crea un archivo index.js. Pega el siguiente fragmento de código en el archivo server/index.js que acabas de crear:
En el fragmento de código anterior, importamos el archivo events.proto que definimos antes y lo asignamos a la variable PROTO_PATH. Luego, lo cargamos con el método loadSync de la biblioteca protoLoader. Después, guardamos las definiciones de proto en la variable eventsProto, que las contiene todas.
A continuación, agrega el siguiente fragmento de código justo después de la variable eventsProto en el archivo server/index.js que definimos antes.
En el fragmento de código anterior, requerimos el paquete node:crypto y su función randomUUID, que sirve para generar cadenas únicas aleatorias para los ID de nuestros eventos. Como en este tutorial usamos una base de datos en memoria, la definiremos como un arreglo para almacenar la lista de eventos. Luego, configuraremos la instancia del servidor con una nueva llamada al método grpc.Server.
A continuación, registraremos los servicios de la aplicación. Para ello, agrega el siguiente fragmento de código justo después de la variable server del fragmento anterior:
En el fragmento de código anterior, llamamos al método addService en la instancia del servidor gRPC para registrar los servicios de la aplicación. En esencia, se trata de operaciones para crear, leer y actualizar eventos.
Para iniciar el servidor de la aplicación, pega el siguiente fragmento de código justo después del método addService del fragmento anterior.
Crear el cliente gRPC
Siguiendo la estructura de carpetas anterior, crea una carpeta client en el directorio raíz de la aplicación y, dentro de ella, crea dos archivos: index.js y app.js. Pega el siguiente fragmento de código en el archivo client/app.js.
En el fragmento de código anterior, importamos las definiciones de proto que creamos antes y las cargamos con protoLoader. Conectamos el cliente grpc a la dirección IP de la aplicación del servidor y exportamos el servicio de eventos con el nombre de variable client. También agregamos un certificado SSL al cliente para autorizar y cifrar las comunicaciones entre el cliente y el servidor.
Luego, pega el siguiente fragmento de código en el archivo client/index.js:
En el fragmento de código anterior, importamos event-service desde el archivo client/app.js. Después, configuramos un servidor Express con endpoints sencillos para gestionar la creation, la update, la fetch y la delete de eventos mediante llamadas remotas a la aplicación del servidor con gRPC.
Probar las aplicaciones del servidor y del cliente
En este punto, podemos probar lo que hicimos para asegurarnos de que todo vaya bien.
El servidor
Ve al directorio raíz del proyecto desde la terminal y ejecuta los siguientes comandos:
La aplicación del servidor debería estar disponible en http://localhost:50051:
El cliente
Abre una nueva ventana de terminal, ve a la carpeta client desde el directorio raíz de la aplicación y ejecuta los siguientes comandos:
La aplicación debería estar disponible en http://localhost:50050:
Para probarla, ve a localhost:50050 en tu navegador o usa una herramienta para probar APIs, como Postman. Deberías ver el evento predeterminado que agregamos inicialmente a nuestro arreglo de eventos. La respuesta debería ser igual a la de la siguiente captura de pantalla:

Autenticar y proteger la API gRPC
El protocolo gRPC admite varios mecanismos de autenticación, por lo que se adapta fácilmente a sistemas nuevos y existentes. Podemos implementar la autenticación en las comunicaciones entre clientes y servidores gRPC con mecanismos recomendados, como SSL y TLS, con o sin autenticación basada en tokens de Google. También podemos crear una autenticación personalizada extendiendo la función de autenticación integrada en gRPC.
De forma predeterminada, gRPC incluye los siguientes mecanismos de autenticación:
SSL y TLS para autenticar el servidor y cifrar los datos intercambiados entre el cliente y el servidor
ALTS (un protocolo de autenticación y transporte mutuo diseñado por Google) para proteger las comunicaciones RPC de las aplicaciones que se ejecutan en Google Cloud Platform (GCP)
Un mecanismo genérico de autenticación basada en tokens para adjuntar credenciales basadas en metadatos a las solicitudes y respuestas
En este tutorial implementaremos la autenticación con SSL, como mencionamos en la introducción, y luego modificaremos los archivos client/app.js y server/index.js para incorporar este cambio.
Generar un certificado SSL con OpenSSL
Primero, generemos un certificado SSL con OpenSSL. Para este proceso, necesitarás tener OpenSSL instalado y permiso para ejecutar scripts de Bash. Estos requisitos son fundamentales para evitar errores de permisos.
En la estructura de carpetas, crea una carpeta scripts y, dentro de ella, un archivo llamado generate-certs.sh. Pega el siguiente fragmento de código en ese archivo:
El código anterior genera los certificados SSL necesarios para establecer una conexión segura y cifrada entre las aplicaciones del servidor y del cliente. Al ejecutarse, crea una carpeta certs, genera los certificados SSL del servidor y del cliente con OpenSSL y los guarda en la carpeta certs. Para obtener más información sobre estas configuraciones y su funcionamiento, visita el sitio web de OpenSSL.
Generar un certificado SSL para la aplicación con npm
Ahora, usa el script para generar un certificado SSL para tu aplicación. Ejecuta los siguientes comandos en la terminal, desde el directorio raíz de la aplicación.
Esto crea una carpeta certs que contiene los certificados SSL generados.
Ten en cuenta que se requieren algunos privilegios de administrador. Si aparece un error de permisos al ejecutar el script, usa los siguientes comandos para otorgarle el permiso de ejecución y vuelve a intentarlo.
Deberías ver el siguiente resultado en la terminal:
Actualizar los archivos client/app.js y server/index.js
Hasta ahora, generamos los certificados SSL necesarios para autenticar nuestras API gRPC. Ahora modificaremos los archivos client/index.js y server/index.js para que funcionen con estos certificados.
En el archivo client/app.js actualizado que se muestra a continuación, incorporamos el módulo fs para leer los certificados generados. Luego, usamos esos certificados para crear credenciales SSL de gRPC y, por último, las aplicamos al servicio gRPC.
También incorporamos el módulo fs en el archivo server/index.js actualizado que se muestra a continuación para leer los certificados generados. Luego, usamos esos certificados para crear credenciales SSL de gRPC y las aplicamos al servidor.
Ejecutar las aplicaciones del servidor y del cliente
Implementamos correctamente una solución de gestión de eventos con las especificaciones de gRPC. Para probar los endpoints, inicia la aplicación desde la terminal siguiendo los pasos que se indican a continuación.
El servidor
Ve al directorio raíz del proyecto desde la terminal y ejecuta los siguientes comandos:
Después de ejecutarlos, la aplicación del servidor debería estar disponible en http://0.0.0.0:50051:
El cliente
Abre una nueva ventana de la terminal, ve a la carpeta client desde el directorio raíz de la aplicación y ejecuta los siguientes comandos:
Después de ejecutarlos, la aplicación del cliente debería estar disponible en http://localhost:50050:
Para probar la aplicación, ve a localhost:50050 en tu navegador o usa una herramienta para probar API, como Postman. Deberías ver el evento predeterminado que agregamos inicialmente a nuestro arreglo de eventos. La respuesta debería coincidir con la siguiente captura de pantalla:

Puedes probar otros endpoints agregados a la aplicación para asegurarte de que todo funcione como esperas.
¡Creaste una API segura con gRPC!
En este tutorial, creamos una API sencilla con gRPC y Node.js, y explicamos cómo funciona y cuáles son sus numerosas ventajas, como HTTP/2 y SSL/TLS para la autenticación y el cifrado de extremo a extremo, que mejoran la seguridad de las API.
A pesar de estas ventajas, gRPC también tiene puntos débiles: compatibilidad limitada con navegadores, un formato de datos difícil de leer para las personas, una curva de aprendizaje pronunciada y poca compatibilidad con el almacenamiento en caché en el borde. Sin embargo, gracias a su rendimiento incomparable y su naturaleza multilingüe, gRPC es la mejor opción para la comunicación entre microservicios internos. El protocolo gRPC es impresionante y, desde su lanzamiento inicial en agosto de 2016, ha logrado una adopción considerable en la industria. Sin duda, seguirá creciendo.
Hay muchas otras cosas que puedes hacer con gRPC. El ejemplo de este tutorial es apenas la punta del iceberg de todo lo que ofrece. Consulta la documentación para ampliar tus conocimientos sobre gRPC y mejorar los procesos de comunicación de tu aplicación, así como las estrategias para mantener la seguridad de gRPC.
