GraphQL y arquitectura de microservicios

176

Estoy tratando de entender dónde GraphQL es más adecuado para usar dentro de una arquitectura de microservicio.

Existe cierto debate acerca de tener solo 1 esquema GraphQL que funcione como API Gateway que envía la solicitud a los microservicios específicos y coacciona su respuesta. Los microservicios aún usarían el protocolo REST / Thrift para el pensamiento de comunicación.

Otro enfoque es tener múltiples esquemas GraphQL uno por microservicio. Tener un servidor API Gateway más pequeño que enruta la solicitud al microservicio objetivo con toda la información de la solicitud + la consulta GraphQL.

1er enfoque

Tener 1 GraphQL Schema como API Gateway tendrá un inconveniente donde cada vez que cambie la entrada / salida de su contrato de microservicio, tenemos que cambiar el Esquema GraphQL en consecuencia en el lado de la API Gateway.

2º enfoque

Si usa un esquema GraphQL múltiple por microservicios, tenga sentido de alguna manera porque GraphQL aplica una definición de esquema y el consumidor deberá respetar la entrada / salida dada por el microservicio.

Preguntas

  • ¿Crees que GraphQL es el adecuado para diseñar la arquitectura de microservicios?

  • ¿Cómo diseñaría una API Gateway con una posible implementación de GraphQL?

Fabrizio Fenoglio
fuente

Respuestas:

242

Definitivamente enfoque # 1.

Hacer que sus clientes hablen con múltiples servicios GraphQL (como en el enfoque n. ° 2) anula por completo el propósito de usar GraphQL en primer lugar, que es proporcionar un esquema sobre todos los datos de la aplicación para permitir obtenerlos en un solo viaje de ida y vuelta.

Tener una arquitectura de nada compartido puede parecer razonable desde la perspectiva de los microservicios, pero para su código del lado del cliente es una pesadilla absoluta, porque cada vez que cambia uno de sus microservicios, debe actualizar a todos sus clientes. Definitivamente te arrepentirás de eso.

GraphQL y los microservicios encajan perfectamente, porque GraphQL oculta el hecho de que los clientes tienen una arquitectura de microservicio. Desde una perspectiva de back-end, desea dividir todo en microservicios, pero desde una perspectiva de interfaz, le gustaría que todos sus datos provengan de una sola API. Usar GraphQL es la mejor manera que conozco que te permite hacer ambas cosas. Le permite dividir su backend en microservicios, al tiempo que proporciona una API única para todas sus aplicaciones y permite unir datos entre diferentes servicios.

Si no desea utilizar REST para sus microservicios, puede hacer que cada uno de ellos tenga su propia API GraphQL, pero aún debe tener una puerta de enlace API. La razón por la cual las personas usan las puertas de enlace API es para que sea más manejable llamar a microservicios desde aplicaciones cliente, no porque se ajuste bien al patrón de microservicios.

ayudante
fuente
2
@helfer: Esto realmente tiene sentido :) gracias. Tengo algunas preguntas además de esta hermosa respuesta. - ¿Estás diciendo que GraphQL tiene que usarse como puerta de enlace API? - Digamos que tengo un microservicio de pedidos que expone un punto final REST o GraphQL. Una vez que termine con él, ¿tengo que actualizar el esquema principal de GraphQL para reflejar exactamente los mismos datos que expondrá el microservicio? ¿No suena duplicación o alejándose de la cultura del microservicio que debería implementarse de forma independiente? ¿Cualquier cambio en un microservicio debe reflejarse / duplicarse en el esquema principal de GraphQL?
Fabrizio Fenoglio
13
@Fabrizio Lo bueno de GraphQL es que incluso si cambia la API REST del backend, el esquema GraphQL puede seguir siendo el mismo, siempre que haya una manera de obtener los datos que el servicio REST expuso anteriormente. Si expone más datos, entonces la forma canónica de lidiar con esto es simplemente agregar nuevos campos / tipos al esquema existente. La gente de Facebook que creó GraphQL me dijo que nunca habían hecho un cambio radical en su esquema en cuatro años. Todos los cambios que hicieron fueron aditivos, lo que significa que los nuevos clientes podrían usar la nueva funcionalidad, mientras que los clientes antiguos continuarían trabajando.
helfer
44
¡Correcto! :) Gracias por escribir esto! ¡Te estoy siguiendo en Medium y en github a través de repos de apollo! ¡Tus artículos y publicaciones son muy valiosas! :) Sigan con el buen trabajo! ¡También creo que un artículo medio con el tema GraphQL + Microservices será muy divertido de leer!
Fabrizio Fenoglio
1
Gracias, lo tendré en cuenta. Definitivamente estoy planeando escribir sobre GraphQL y Microservicios en algún momento, pero probablemente no en las próximas semanas.
helfer
¿Qué tal la combinación de la opción # 2 y github.com/AEB-labs/graphql-weaver ?
Mohsen
35

Vea el artículo aquí , que dice cómo y por qué el enfoque n. ° 1 funciona mejor. También mire la imagen a continuación tomada del artículo que mencioné: ingrese la descripción de la imagen aquí

Uno de los principales beneficios de tener todo detrás de un único punto final es que los datos se pueden enrutar de manera más efectiva que si cada solicitud tuviera su propio servicio. Si bien este es el valor a menudo promocionado de GraphQL, una reducción en la complejidad y la fluencia del servicio, la estructura de datos resultante también permite que la propiedad de los datos esté extremadamente bien definida y claramente delineada.

Otro beneficio de adoptar GraphQL es el hecho de que puede afirmar fundamentalmente un mayor control sobre el proceso de carga de datos. Debido a que el proceso para los cargadores de datos entra en su propio punto final, puede cumplir la solicitud de forma parcial, total o con advertencias, y así controlar de forma extremadamente granular cómo se transfieren los datos.

El siguiente artículo explica muy bien estos dos beneficios junto con otros: https://nordicapis.com/7-unique-benefits-of-using-graphql-in-microservices/

Enayat
fuente
Hola, perdón por las preguntas novatas, pero ¿no es su puerta de enlace GraphQL un nuevo punto de retención? Por ejemplo, si tengo un servicio de canasta que de repente está demasiado soliculado, ¿no se rompería también mi puerta de enlace GraphQL? Básicamente, no estoy seguro de su función, ¿se supone que esta puerta de enlace contiene muchos resolvers para cada servicio?
Eric Burel
1
@EricBurel Gracias por la pregunta. En realidad, por lo que entendí del artículo, todos los esquemas de diferentes servicios están unificados bajo un esquema GraphQL, por lo que, como mencionó, otros servicios aún residen en sus propios conjuntos de datos. En cuanto a la posibilidad de una sola fuente de falla para la puerta de enlace GraphQL, siempre hay otras opciones, como proporcionar un plan de respaldo. Lea este artículo ( labs.getninjas.com.br/… ) para obtener más información. Espero que esto ayude.
Enayat
¿Cómo se prueba la puerta de enlace API central y los servicios individuales? ¿Estás haciendo integración o burlándote de la respuesta http?
Jaime Sangcap
7

Para el enfoque n. ° 2, de hecho, esa es la forma en que elijo, porque es mucho más fácil que mantener la molesta puerta de enlace API manualmente. De esta manera puede desarrollar sus servicios de forma independiente. Hacer la vida mucho más fácil: P

Hay algunas herramientas excelentes para combinar esquemas en uno, por ejemplo, graphql-weaver y las herramientas graphql de apollo , estoy usando graphql-weaver, es fácil de usar y funciona muy bien.

HFX
fuente
Usar GraphQL en Android es imprescindible para crear un archivo .graphql con todas las consultas. ¿O puedo crearlos en el código sin este archivo?
MauroAlexandro
1
@MauroAlexandro No soy un chico de Android, pero puedes tener las consultas en diferentes archivos. Es más un problema de diseño. En mi humilde opinión, prefiero el primero :)
HFX
5

A mediados de 2019, la solución para el Primer Enfoque ahora tiene el nombre de " Federación de Esquemas " acuñado por la gente de Apolo (Anteriormente, esto se denominaba costura de GraphQL). También proponen los módulos @apollo/federationy @apollo/gatewaypara esto.

AGREGAR: Tenga en cuenta que con Schema Federation no puede modificar el esquema en el nivel de puerta de enlace. Entonces, por cada bit que necesite en su esquema, debe tener un servicio separado.

vanthome
fuente
También es válido saber que esta solución requiere Apollo Server, que está ligeramente limitado en la versión gratuita (máximo 25 millones de consultas por mes)
Marx
0

A partir de 2019, la mejor manera es escribir microservicios que implementen la especificación de puerta de enlace de Apolo y luego pegar estos servicios utilizando una puerta de enlace siguiendo el enfoque n. ° 1. La forma más rápida de construir la puerta de enlace es una imagen acoplable como esta. Luego, use docker-compose para iniciar todos los servicios simultáneamente:

version: '3'

services:
    service1:
        build: service1
    service2:
        build: service2
    gateway:
        ports:
            - 80:80
        image: xmorse/apollo-federation-gateway
        environment: 
            - CACHE_MAX_AGE=5
            - "FORWARD_HEADERS=Authorization, X-Custom-Header" # default is Authorization, pass '' to reset
            - URL_0=http://service1
            - URL_1=http://service2
morse
fuente
0

En la forma en que se describe en esta pregunta, creo que el uso de una puerta de enlace API personalizada como servicio de orquestación puede tener mucho sentido para aplicaciones complejas enfocadas en la empresa. GraphQL puede ser una buena opción tecnológica para ese servicio de orquestación, al menos en lo que respecta a las consultas. La ventaja de su primer enfoque (un esquema para todos los microservicios) es la capacidad de unir los datos de múltiples microservicios en una sola solicitud. Eso puede, o no, ser muy importante dependiendo de su situación. Si la GUI requiere procesar datos de múltiples microservicios a la vez, este enfoque puede simplificar el código del cliente de modo que una sola llamada pueda devolver datos que sean adecuados para el enlace de datos con los elementos de la GUI de marcos como Angular o React. Esta ventaja no se aplica a las mutaciones.

La desventaja es el acoplamiento estrecho entre las API de datos y el servicio de orquestación. Los lanzamientos ya no pueden ser atómicos. Si se abstiene de introducir cambios rotos hacia atrás en sus API de datos, esto puede introducir complejidad solo cuando se revierte una versión. Por ejemplo, si está a punto de lanzar nuevas versiones de dos API de datos con los cambios correspondientes en el servicio de orquestación y necesita revertir una de esas versiones pero no la otra, entonces se verá obligado a revertir las tres de todos modos.

En esta comparación de GraphQL vs REST , encontrará que GraphQL no es tan eficiente como las API RESTful, por lo que no recomendaría reemplazar REST con GraphQL para las API de datos.

Glenn
fuente
0

Para la pregunta 1, Intuit reconoció el poder de GraphQL hace unos años cuando anunció el cambio al ecosistema One Intuit API ( https://www.slideshare.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integrations -quickbooks-connect-2017 ). Intuit optó por el enfoque 1. El inconveniente que usted menciona en realidad impide que los desarrolladores introduzcan cambios de esquema que podrían interrumpir las aplicaciones del cliente.

GraphQL ha ayudado a mejorar la productividad de los desarrolladores de varias maneras.

  1. Al diseñar un nuevo microservicio para un dominio, los ingenieros (backend / frontend / stakeholders) acuerdan un esquema para las entidades del dominio. Una vez que se aprueba el esquema, se fusiona con el esquema de dominio maestro (universal) y se implementa en la puerta de enlace. Los ingenieros de front end pueden comenzar a codificar aplicaciones cliente con este esquema mientras los ingenieros de back-end implementan la funcionalidad. Tener un esquema universal significa que no hay dos microservicios con funcionalidad redundante.
  2. GraphQL ha ayudado a las aplicaciones cliente a ser más simples y rápidas. ¿Desea recuperar / actualizar datos de múltiples microservicios? Lo único que deben hacer las aplicaciones del cliente es activar UNA solicitud de GraphQL y la capa de abstracción API Gateway se encargará de buscar y recopilar datos de múltiples fuentes (microservicios). Los marcos de código abierto como Apollo ( https://www.apollographql.com/ ) han acelerado el ritmo de adopción de GraphQL.

  3. Dado que los dispositivos móviles son la primera opción para las aplicaciones modernas, es importante diseñar para requisitos de ancho de banda de datos más bajos desde cero. GraphQL ayuda al permitir que las aplicaciones del cliente soliciten solo campos específicos.

Para la pregunta 2: Creamos una capa de abstracción personalizada en la API Gateway que sabe qué parte del esquema pertenece a qué servicio (proveedor). Cuando llega una solicitud de consulta, la capa de abstracción reenvía la solicitud a los servicios apropiados. Una vez que el servicio subyacente devuelve la respuesta, la capa de abstracción es responsable de devolver los campos solicitados.

Sin embargo, hoy en día existen varias plataformas (servidor Apollo, graphql-yoga, etc.) que permiten construir una capa de abstracción GraphQL en muy poco tiempo.

Nacharya
fuente
0

He estado trabajando con GraphQL y microservicios

Según mi experiencia, lo que funciona para mí es una combinación de ambos enfoques, dependiendo de la funcionalidad / uso, nunca tendré una sola puerta de enlace como en el enfoque 1 ... pero no un gráfico por cada microservicio como enfoque 2.

Por ejemplo, basado en la imagen de la respuesta de Enayat, lo que haría en este caso es tener 3 puertas de enlace de gráficos (no 5 como en la imagen)

ingrese la descripción de la imagen aquí

  • Aplicación (producto, cesta, envío, inventario, necesario / vinculado a otros servicios)

  • Pago

  • Usuario

De esta manera, debe prestar especial atención al diseño de los datos mínimos necesarios / vinculados expuestos de los servicios dependientes, como un token de autenticación, ID de usuario, ID de pago, estado de pago

En mi experiencia, por ejemplo, tengo la puerta de enlace "Usuario", en ese GraphQL tengo las consultas / mutaciones del usuario, iniciar sesión, iniciar sesión, cerrar sesión, cambiar contraseña, recuperar correo electrónico, confirmar correo electrónico, borrar cuenta, editar perfil, cargar imagen , etc ... este gráfico por sí solo es bastante grande !, está separado porque al final los otros servicios / puertas de enlace solo se preocupan por la información resultante, como ID de usuario, nombre o token.

De esta manera es más fácil ...

  • Escale / apague los diferentes nodos de puertas de enlace en función de su uso. (por ejemplo, es posible que las personas no siempre estén editando su perfil o pagando ... pero la búsqueda de productos podría usarse con más frecuencia).

  • Una vez que las puertas de enlace maduran, crecen, se conoce su uso o tiene más experiencia en el dominio, puede identificar cuáles son la parte del esquema que podría tener su propia puerta de enlace (... me ocurrió con un gran esquema que interactúa con los repositorios git , Separé la puerta de enlace que interactúa con un repositorio y vi que la única entrada necesaria / información vinculada era ... la ruta de la carpeta y la rama esperada)

  • La historia de sus repositorios es más clara y puede tener un repositorio / desarrollador / equipo dedicado a una puerta de enlace y sus microservicios involucrados.

ACTUALIZAR:

Tengo un clúster de kubernetes en línea que usa el mismo enfoque que describo aquí con todos los backends que usan GraphQL, todos de código abierto, aquí está el repositorio principal: https://github.com/vicjicaman/microservice-realm

Esta es una actualización de mi respuesta porque creo que es mejor si la respuesta / enfoque está respaldado por un código que se está ejecutando y puede consultarse / revisarse, espero que esto ayude.

Victor Jiménez
fuente
-3

Como la arquitectura de microservicios no tiene una definición adecuada, no existe un modelo específico para este estilo pero, la mayoría de ellos tendrá pocas características notables. En el caso de la arquitectura de microservicios, cada servicio puede dividirse en pequeños componentes individuales, que pueden ser ajustado e implementado individualmente sin afectar la integridad de la aplicación. Esto significa que simplemente puede cambiar algunos servicios sin tener que volver a implementar aplicaciones a través del desarrollo de aplicaciones de microservicios personalizados .

Demetrius Franco
fuente
Aunque carece de una "definición adecuada", es un concepto bien entendido y claramente delimitado en el contexto de la pregunta. Aparte de eso, su respuesta no aborda la pregunta en absoluto.
Roy Prins
-7

Más sobre microservicios, creo que GraphQL también podría funcionar perfectamente en la arquitectura sin servidor. No uso GraphQL pero tengo mi propio proyecto similar . Lo uso como un agregador que invoca y concentra muchas funciones en un solo resultado. Creo que podría aplicar el mismo patrón para GraphQL.

Giap Nguyen
fuente
2
Lo sentimos, pero esto no es relevante para la pregunta del OP en absoluto. La pregunta es sobre dos enfoques específicos que usan GraphQL. Esto podría haberse puesto mejor como comentario.
tiomno