La API REST ha sido un pilar de la programación web durante mucho tiempo. Pero recientemente gRPC ha comenzado a invadir su territorio. Resulta que hay algunas muy buenas razones para eso. En este tutorial, aprenderá sobre los entresijos de gRPC y cómo se compara con REST.
Una de las mayores diferencias entre REST y gRPC es el formato de la carga útil. Los mensajes REST normalmente contienen JSON. Este no es un requisito estricto y, en teoría, puede enviar cualquier respuesta como respuesta, pero en la práctica, todo el ecosistema REST, incluidas las herramientas, las mejores prácticas y los tutoriales, se centra en JSON. Es seguro decir que, con muy pocas excepciones, las API REST aceptan y devuelven JSON.
gRPC, por otro lado, acepta y devuelve los mensajes de Protobuf. Discutiré la escritura fuerte más adelante, pero solo desde el punto de vista del rendimiento, Protobuf es un formato muy eficiente y empaquetado. JSON, por otro lado, es un formato textual. Puede comprimir JSON, pero luego pierde el beneficio de un formato de texto que puede esperar fácilmente.
Comparemos los protocolos de transferencia que utilizan REST y gRPC. REST, como se mencionó anteriormente, depende en gran medida de HTTP (generalmente HTTP 1.1) y del modelo de solicitud-respuesta. Por otro lado, gRPC usa el protocolo HTTP / 2 más nuevo.
Hay varios problemas que afectan a HTTP 1.1 que HTTP / 2 corrige. Aquí están los principales.
HTTP 1.0 RFC 1945 es un RFC de 60 páginas. HTTP 1.1 se describió originalmente en RFC 2616, que aumentó hasta 176 páginas. Sin embargo, más tarde, el IETF lo dividió en seis documentos diferentes, RFC 7230, 7231, 7232, 7233, 7234 y 7235, con un número de páginas combinado aún mayor. HTTP 1.1 permite muchas partes opcionales que contribuyen a su tamaño y complejidad.
La tendencia de las páginas web es aumentar tanto el tamaño total de la página (1.9MB en promedio) como el número de objetos en la página que requieren solicitudes individuales. Dado que cada objeto requiere una solicitud HTTP por separado, esta multiplicación de objetos separados aumenta la carga en los servidores web de manera significativa y ralentiza los tiempos de carga de la página para los usuarios.
HTTP 1.1 es sensible a la latencia. Se requiere un protocolo de enlace de TCP para cada solicitud individual, y un mayor número de solicitudes tiene un costo significativo en el tiempo necesario para cargar una página. La mejora continua en el ancho de banda disponible no resuelve estos problemas de latencia en la mayoría de los casos.
La restricción en el número de conexiones al mismo dominio (que solía ser solo 2, hoy 6-8) reduce significativamente la capacidad de enviar múltiples solicitudes en paralelo.
Con la canalización HTTP, puede enviar una solicitud mientras espera la respuesta a una solicitud anterior, creando una cola de manera efectiva. Pero eso introduce otros problemas. Si su solicitud se bloquea tras una solicitud lenta, su tiempo de respuesta se verá afectado..
Hay otras preocupaciones como el rendimiento y las penalizaciones de recursos al cambiar de línea. Por el momento, la canalización HTTP no está ampliamente habilitada.
HTTP / 2, que surgió del SPDY de Google, mantiene las premisas y los paradigmas básicos de HTTP:
http: //
y https: //
Esquemas URLPero las partes opcionales de HTTP 1.1 fueron eliminadas.
Para abordar el protocolo de negociación debido al esquema de URL compartido, hay un encabezado de actualización. Además, aquí hay una sorpresa para usted: ¡el protocolo HTTP / 2 es binario! Si ha estado cerca de los protocolos de Internet, entonces sabe que los protocolos textuales se consideran rey porque son más fáciles para que los humanos puedan resolver problemas y construir solicitudes manualmente. Pero, en la práctica, la mayoría de los servidores de hoy usan encriptación y compresión de todos modos. El marco binario ayuda en gran medida a reducir la complejidad del manejo de marcos en HTTP 1.1.
Sin embargo, la mejora principal de HTTP / 2 es que utiliza flujos multiplexados. Una sola conexión HTTP / 2 TCP puede admitir muchas transmisiones bidireccionales. Estas secuencias se pueden intercalar (sin colas) y se pueden enviar múltiples solicitudes al mismo tiempo sin necesidad de establecer nuevas conexiones TCP para cada una. Además, los servidores ahora pueden enviar notificaciones a los clientes a través de la conexión establecida (inserción HTTP / 2).
REST es una API interesante. Está construido muy bien sobre HTTP. No solo utiliza HTTP como un transporte, sino que abarca todas sus características y crea un marco conceptual consistente encima de él. En teoría, suena genial. En la práctica, ha sido muy difícil implementar REST correctamente.
No me malinterprete: REST ha sido y es muy exitoso, pero la mayoría de las implementaciones no se adhieren completamente a la filosofía REST y solo utilizan un subconjunto de sus principios. La razón es que en realidad es bastante difícil mapear la lógica de negocios y las operaciones en el estricto mundo REST.
El modelo conceptual utilizado por gRPC es tener servicios con interfaces claras y mensajes estructurados para solicitudes y respuestas. Este modelo se traduce directamente de conceptos del lenguaje de programación como interfaces, funciones, métodos y estructuras de datos. También permite que gRPC genere automáticamente las bibliotecas cliente para usted.
REST solo admite el modelo de solicitud-respuesta disponible en HTTP 1.x. Pero gRPC aprovecha al máximo las capacidades de HTTP / 2 y le permite transmitir información constantemente. Hay varios tipos de streaming.
El servidor envía una secuencia de respuestas después de recibir un mensaje de solicitud de cliente. Después de devolver todas sus respuestas, los detalles de estado del servidor y los metadatos de seguimiento opcionales se devuelven para completar en el lado del servidor. El cliente se completa una vez que tiene todas las respuestas del servidor..
El cliente envía una secuencia de múltiples solicitudes al servidor. El servidor envía una respuesta única, por lo general, pero no necesariamente, después de haber recibido todas las solicitudes del cliente, junto con sus detalles de estado y metadatos finales opcionales..
En este escenario, el cliente y el servidor se envían información en forma bastante libre (excepto que el cliente inicia la secuencia). Finalmente, el cliente cierra la conexión..
El paradigma REST no obliga a ninguna estructura para la carga útil intercambiada. Es típicamente JSON. Los consumidores no tienen un mecanismo formal para coordinar el formato de las solicitudes y respuestas. El JSON debe ser serializado y convertido al lenguaje de programación de destino, tanto en el lado del servidor como en el del cliente. La serialización es otro paso en la cadena que introduce la posibilidad de errores, así como la sobrecarga de rendimiento..
El contrato de servicio gRPC tiene mensajes tipificados que se convierten automáticamente de su representación de Protobuf a su lenguaje de programación de elección tanto en el servidor como en el cliente..
JSON, por otro lado, es teóricamente más flexible porque puede enviar datos dinámicos y no tiene que adherirse a una estructura rígida.
El soporte para gRPC en el navegador no es tan maduro. Hoy en día, gRPC se usa principalmente para servicios internos que no están expuestos directamente al mundo.
Si desea consumir un servicio gRPC desde una aplicación web o desde un idioma no compatible con gRPC, entonces gRPC ofrece una puerta de enlace REST API para exponer su servicio. El complemento de pasarela gRPC genera un servidor de API REST completo con un proxy inverso y documentación de Swagger.
Con este enfoque, pierde la mayoría de los beneficios de gRPC, pero si necesita proporcionar acceso a un servicio existente, puede hacerlo sin implementar el servicio dos veces.
En el mundo de los microservicios, gRPC se convertirá en dominante muy pronto. Los beneficios de rendimiento y la facilidad de desarrollo son demasiado buenos para dejarlos pasar. Sin embargo, no se equivoque, REST seguirá existiendo durante mucho tiempo. Todavía sobresale por las API expuestas públicamente y por razones de compatibilidad con versiones anteriores.