Architecture GraphQL et Microservice

176

J'essaie de comprendre où GraphQL est le plus approprié à utiliser dans une architecture Microservice.

Il y a un débat sur le fait de n'avoir qu'un seul schéma GraphQL qui fonctionne comme API Gateway qui transmet la demande aux microservices ciblés et contraint leur réponse. Les microservices utiliseraient toujours le protocole REST / Thrift pour la communication.

Une autre approche consiste plutôt à avoir plusieurs schémas GraphQL un par microservice. Avoir un serveur API Gateway plus petit qui achemine la demande vers le microservice ciblé avec toutes les informations de la demande + la requête GraphQL.

1ère approche

Avoir 1 schéma GraphQL en tant que passerelle API aura un inconvénient: chaque fois que vous modifiez votre entrée / sortie de contrat de microservice, nous devons modifier le schéma GraphQL en conséquence du côté de la passerelle API.

2ème approche

Si vous utilisez plusieurs schémas GraphQL par microservices, cela a du sens car GraphQL applique une définition de schéma, et le consommateur devra respecter les entrées / sorties fournies par le microservice.

Des questions

  • Trouvez-vous que GraphQL est la solution idéale pour concevoir une architecture de microservices?

  • Comment concevriez-vous une passerelle API avec une implémentation possible de GraphQL?

Fabrizio Fenoglio
la source

Réponses:

242

Approche définitivement n ° 1.

Faire en sorte que vos clients parlent à plusieurs services GraphQL (comme dans l'approche n ° 2) va totalement à l'encontre de l'objectif d'utiliser GraphQL en premier lieu, qui est de fournir un schéma sur l' ensemble des données de votre application pour permettre de les récupérer en un seul aller-retour.

Avoir une architecture sans partage peut sembler raisonnable du point de vue des microservices, mais pour votre code côté client, c'est un cauchemar absolu, car chaque fois que vous changez l'un de vos microservices, vous devez mettre à jour tous vos clients. Vous allez certainement le regretter.

GraphQL et les microservices sont parfaitement adaptés, car GraphQL cache le fait que vous avez une architecture de microservices aux clients. Du point de vue du backend, vous souhaitez tout diviser en microservices, mais du point de vue du frontend, vous souhaitez que toutes vos données proviennent d'une seule API. Utiliser GraphQL est le meilleur moyen que je connaisse qui vous permet de faire les deux. Il vous permet de diviser votre backend en microservices, tout en fournissant une seule API à toutes vos applications et en autorisant les jointures entre les données de différents services.

Si vous ne souhaitez pas utiliser REST pour vos microservices, vous pouvez bien sûr faire en sorte que chacun d'eux ait sa propre API GraphQL, mais vous devez tout de même disposer d'une passerelle API. La raison pour laquelle les gens utilisent les passerelles d'API est de rendre plus gérable l'appel de microservices à partir d'applications clientes, et non parce que cela s'intègre bien dans le modèle de microservices.

aide
la source
2
@helfer: Cela a vraiment du sens :) merci. J'ai quelques questions en plus de cette magnifique réponse. - Vous dites que GraphQL doit être utilisé comme passerelle API? - Disons que j'ai un microservice de commande qui expose un point final REST ou GraphQL. Une fois que j'en ai terminé, je dois mettre à jour le schéma GraphQL principal pour refléter exactement les mêmes données que le microservice exposera? Cela ne semble-t-il pas une duplication ou s'éloigner de la culture des microservices qui devrait être déployée de manière indépendante? Les modifications apportées à un microservice doivent-elles être reflétées / dupliquées dans le schéma principal de GraphQL?
Fabrizio Fenoglio
13
@Fabrizio la bonne chose avec GraphQL est que même si l'API REST du backend change, le schéma GraphQL peut toujours rester le même, tant qu'il existe un moyen d'obtenir les données précédemment exposées par le service REST. Si cela expose plus de données, la manière canonique de gérer cela consiste simplement à ajouter de nouveaux champs / types au schéma existant. Les gens de Facebook qui ont créé GraphQL m'ont dit qu'ils n'avaient jamais apporté de changement radical à leur schéma en quatre ans. Tous les changements qu'ils ont apportés étaient additifs, ce qui signifie que les nouveaux clients pouvaient utiliser la nouvelle fonctionnalité, tandis que les anciens clients continueraient à fonctionner.
helfer
4
Droite! :) Merci d'écrire ceci! Je vous suis sur Medium et sur github via Apollo Repos! Vos articles et messages sont très précieux! :) Continuez votre bon travail! Je pense aussi qu'un article moyen avec le sujet GraphQL + Microservices sera très agréable à lire!
Fabrizio Fenoglio
1
Merci, je vais garder cela à l'esprit. Je prévois vraiment d'écrire sur GraphQL et Microservices à un moment donné, mais probablement pas dans les prochaines semaines.
helfer
Que diriez-vous de la combinaison de l'option n ° 2 et de github.com/AEB-labs/graphql-weaver ?
Mohsen
35

Voir l'article ici , qui explique comment et pourquoi l'approche n ° 1 fonctionne mieux. Regardez également l'image ci-dessous tirée de l'article que j'ai mentionné: entrez la description de l'image ici

L'un des principaux avantages d'avoir tout derrière un seul point de terminaison est que les données peuvent être acheminées plus efficacement que si chaque demande avait son propre service. Bien que ce soit la valeur souvent vantée de GraphQL, une réduction de la complexité et de la dérive des services, la structure de données qui en résulte permet également à la propriété des données d'être extrêmement bien définie et clairement délimitée.

Un autre avantage de l'adoption de GraphQL est le fait que vous pouvez fondamentalement affirmer un meilleur contrôle sur le processus de chargement des données. Étant donné que le processus des chargeurs de données se déroule dans son propre point de terminaison, vous pouvez soit honorer la demande partiellement, entièrement, soit avec des mises en garde, et ainsi contrôler de manière extrêmement granulaire la manière dont les données sont transférées.

L'article suivant explique très bien ces deux avantages ainsi que d'autres: https://nordicapis.com/7-unique-benefits-of-using-graphql-in-microservices/

Enayat
la source
Salut, désolé pour les questions noob, mais votre passerelle graphQL n'est-elle pas un nouveau point de rétention? Par exemple, si j'ai un service de panier qui est soudainement trop sollicité, ma passerelle GraphQL ne se cassera-t-elle pas aussi? En gros je ne suis pas sûr de son rôle, cette passerelle est censée contenir beaucoup de résolveurs pour chaque service?
Eric Burel
1
@EricBurel Merci pour la question. En fait, d'après ce que j'ai compris de l'article, tous les schémas de différents services sont unifiés sous un schéma GraphQL, donc comme vous l'avez mentionné, d'autres services résident toujours sur leurs propres ensembles de données. En ce qui concerne la possibilité d'une source unique de défaillance pour la passerelle graphQL, il existe toujours d'autres options comme fournir un plan de sauvegarde. Veuillez lire cet article ( labs.getninjas.com.br/… ) pour plus d'informations. J'espère que cela t'aides.
Enayat
Comment testez-vous la passerelle API centrale et les services individuels? Faites-vous une intégration ou une réponse http moqueuse?
Jaime Sangcap
7

Pour l'approche n ° 2, c'est en fait la façon dont je choisis, car c'est beaucoup plus facile que de maintenir manuellement la passerelle API ennuyeuse. De cette façon, vous pouvez développer vos services de manière indépendante. Simplifiez-vous la vie: P

Il y a quelques outils pour combiner les schémas en un seul, par exemple graphql-tisserand et APOLLO graphql-outils , j'utilise graphql-weaver, il est facile à utiliser et fonctionne très bien.

HFX
la source
Utiliser GraphQL sous Android est impératif que je crée un fichier .graphql avec toutes les requêtes? Ou puis-je simplement les créer dans le code sans ce fichier?
MauroAlexandro
1
@MauroAlexandro Je ne suis pas un gars Android, mais vous pouvez avoir les requêtes dans différents fichiers. C'est plus un problème de conception. IMHO, je préfère le premier :)
HFX
5

À partir de la mi-2019, la solution pour la 1ère approche porte désormais le nom de « Schema Federation », inventé par le peuple Apollo (auparavant, cela était souvent appelé assemblage GraphQL). Ils proposent également les modules @apollo/federationet @apollo/gatewaypour cela.

AJOUTER: Veuillez noter qu'avec Schema Federation, vous ne pouvez pas modifier le schéma au niveau de la passerelle. Ainsi, pour chaque élément dont vous avez besoin dans votre schéma, vous devez disposer d'un service distinct.

vanthome
la source
il est également valable de savoir que cette solution nécessite Apollo Server qui est légèrement limité en version gratuite (max 25 millions de requêtes par mois)
Marx
0

À partir de 2019, le meilleur moyen est d'écrire des microservises qui implémentent la spécification de la passerelle Apollo , puis de coller ces services à l'aide d'une passerelle suivant l'approche n ° 1. Le moyen le plus rapide de créer la passerelle est une image docker comme celle-ci. Ensuite, utilisez docker-compose pour démarrer tous les services simultanément:

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
la source
0

De la manière dont cela est décrit dans cette question, je pense que l'utilisation d'une passerelle API personnalisée en tant que service d'orchestration peut avoir beaucoup de sens pour les applications complexes axées sur l'entreprise. GraphQL peut être un bon choix technologique pour ce service d'orchestration, du moins en ce qui concerne les requêtes. L'avantage de votre première approche (un schéma pour tous les microservices) est la possibilité d'assembler les données de plusieurs microservices en une seule requête. Cela peut ou non être très important en fonction de votre situation. Si l'interface graphique appelle à rendre les données de plusieurs microservices en même temps, cette approche peut simplifier le code client de sorte qu'un seul appel puisse renvoyer des données adaptées à la liaison de données avec les éléments d'interface graphique de frameworks tels que Angular ou React. Cet avantage ne s'applique pas aux mutations.

L'inconvénient est un couplage étroit entre les API de données et le service d'orchestration. Les rejets ne peuvent plus être atomiques. Si vous vous abstenez d'introduire des modifications rétrogrades dans vos API de données, cela ne peut introduire de complexité que lors de la restauration d'une version. Par exemple, si vous êtes sur le point de publier de nouvelles versions de deux API de données avec les modifications correspondantes dans le service d'orchestration et que vous devez annuler l'une de ces versions mais pas l'autre, vous serez quand même obligé de restaurer les trois.

Dans cette comparaison de GraphQL vs REST, vous constaterez que GraphQL n'est pas aussi efficace que les API RESTful, donc je ne recommanderais pas de remplacer REST par GraphQL pour les API de données.

Glenn
la source
0

À la question 1, Intuit a reconnu la puissance de GraphQL il y a quelques années lorsqu'il a annoncé le passage à l'écosystème d'API One Intuit ( https://www.slideshare.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integrations -quickbooks-connect-2017 ). Intuit a choisi de suivre l'approche 1. L'inconvénient que vous mentionnez empêche en fait les développeurs d'introduire des modifications de schéma de rupture susceptibles de perturber les applications clientes.

GraphQL a contribué à améliorer la productivité des développeurs de plusieurs manières.

  1. Lors de la conception d'un nouveau microservice pour un domaine, les ingénieurs (backend / frontend / parties prenantes) conviennent d'un schéma pour les entités du domaine. Une fois le schéma approuvé, il est fusionné avec le schéma du domaine maître (universel) et déployé sur la passerelle.Les ingénieurs front-end peuvent commencer à coder les applications client avec ce schéma tandis que les ingénieurs backend implémentent la fonctionnalité. Avoir un schéma universel signifie qu'il n'y a pas deux microservices avec des fonctionnalités redondantes.
  2. GraphQL a aidé les applications clientes à devenir plus simples et plus rapides. Vous souhaitez récupérer des données / mettre à jour des données vers plusieurs microservices? Toutes les applications clientes doivent lancer une requête GraphQL et la couche d'abstraction API Gateway prendra soin de récupérer et de rassembler les données de plusieurs sources (microservices). Les frameworks open source comme Apollo ( https://www.apollographql.com/ ) ont accéléré le rythme de l'adoption de GraphQL.

  3. Le mobile étant le premier choix pour les applications modernes, il est important de concevoir des besoins en bande passante de données inférieurs à partir de zéro. GraphQL aide en permettant aux applications clientes de demander uniquement des champs spécifiques.

À la question 2: Nous avons créé une couche d'abstraction personnalisée au niveau de la passerelle API qui sait quelle partie du schéma appartient à quel service (fournisseur). Lorsqu'une requête de requête arrive, la couche d'abstraction transmet la requête au (x) service (s) approprié (s). Une fois que le service sous-jacent a renvoyé la réponse, la couche d'abstraction est chargée de renvoyer les champs demandés.

Cependant, il existe aujourd'hui plusieurs plates-formes (serveur Apollo, graphql-yoga, etc.) qui permettent de créer une couche d'abstraction GraphQL en un rien de temps.

Nacharya
la source
0

J'ai travaillé avec GraphQL et des microservices

D'après mon expérience, ce qui fonctionne pour moi est une combinaison des deux approches en fonction de la fonctionnalité / utilisation, je n'aurai jamais une seule passerelle comme dans l'approche 1 ... mais pas un graphql pour chaque microservice comme approche 2.

Par exemple sur la base de l'image de la réponse d'Enayat, ce que je ferais dans ce cas, c'est d'avoir 3 passerelles graphiques (pas 5 comme dans l'image)

entrez la description de l'image ici

  • Application (produit, panier, expédition, inventaire, nécessaire / lié à d'autres services)

  • Paiement

  • Utilisateur

De cette façon, vous devez accorder une attention particulière à la conception des données minimales nécessaires / liées exposées à partir des services dépendants, comme un jeton d'authentification, un identifiant d'utilisateur, un identifiant de paiement, un statut de paiement.

Dans mon expérience par exemple, j'ai la passerelle "Utilisateur", dans ce GraphQL j'ai les requêtes / mutations de l'utilisateur, se connecter, se connecter, se déconnecter, changer le mot de passe, récupérer l'e-mail, confirmer l'e-mail, supprimer le compte, modifier le profil, télécharger l'image , etc ... ce graphe en lui-même est assez volumineux !, il est séparé car à la fin les autres services / passerelles ne se soucient que des informations résultantes comme l'ID utilisateur, le nom ou le jeton.

Cette façon est plus facile de ...

  • Mettez à l'échelle / arrêtez les différents nœuds de passerelles en fonction de leur utilisation. (par exemple, les gens peuvent ne pas toujours modifier leur profil ou payer ... mais la recherche de produits peut être utilisée plus fréquemment).

  • Une fois qu'une passerelle mûrit, grandit, son utilisation est connue ou que vous avez plus d'expertise sur le domaine, vous pouvez identifier la partie du schéma qui pourrait avoir sa propre passerelle (... m'est arrivé avec un énorme schéma qui interagit avec les référentiels git , J'ai séparé la passerelle qui interagit avec un référentiel et j'ai vu que la seule entrée nécessaire / information liée était ... le chemin du dossier et la branche attendue)

  • L'historique de vos référentiels est plus clair et vous pouvez avoir un référentiel / développeur / équipe dédié à une passerelle et à ses microservices impliqués.

METTRE À JOUR:

J'ai un cluster kubernetes en ligne qui utilise la même approche que je décris ici avec tous les backends utilisant GraphQL, tous open source, voici le référentiel principal: https://github.com/vicjicaman/microservice-realm

Ceci est une mise à jour de ma réponse car je pense qu'il est préférable que la réponse / approche soit sauvegardée du code qui est en cours d'exécution et peut être consulté / révisé, j'espère que cela aide.

Victor Jimenez
la source
-3

L'architecture des microservices n'ayant pas de définition correcte, il n'y a pas de modèle spécifique pour ce style mais la plupart d'entre eux présenteront peu de caractéristiques notables.Dans le cas d'une architecture de microservices, chaque service peut être décomposé en petits composants individuels, qui peuvent être individuellement peaufiné et déployé sans affecter l'intégrité de l'application. Cela signifie que vous pouvez simplement modifier quelques services sans recourir au redéploiement d'applications via le développement d'applications de microservices personnalisés .

Démétrius Franco
la source
Même s'il manque une «définition appropriée», il s'agit d'un concept bien compris et clairement délimité dans le contexte de la question. Cela mis à part, votre réponse ne répond pas du tout à la question.
Roy Prins
-7

En savoir plus sur les microservices, je pense que GraphQL pourrait également fonctionner parfaitement dans une architecture sans serveur. Je n'utilise pas GraphQL mais j'ai mon propre projet similaire . Je l'utilise comme un agrégateur qui invoque et concentre de nombreuses fonctions en un seul résultat. Je pense que vous pourriez appliquer le même modèle pour GraphQL.

Giap Nguyen
la source
2
Désolé, mais ce n'est pas du tout pertinent pour la question du PO. La question porte sur deux approches spécifiques utilisant GraphQL. Cela aurait pu être mieux mis en commentaire.
tiomno