Exploitez la puissance de la Fédération GraphQL avec le Schema Stitching. Apprenez à créer une API GraphQL unifiée à partir de plusieurs services, améliorant la scalabilité et la maintenabilité.
Fédération GraphQL : Schema Stitching - Un Guide Complet
Dans le paysage en constante évolution du développement d'applications modernes, le besoin d'architectures scalables et maintenables est devenu primordial. Les microservices, avec leur modularité inhérente et leur déployabilité indépendante, sont devenus une solution populaire. Cependant, la gestion de nombreux microservices peut introduire des complexités, notamment lorsqu'il s'agit d'exposer une API unifiée aux applications clientes. C'est là que la Fédération GraphQL, et plus spécifiquement le Schema Stitching, entre en jeu.
Qu'est-ce que la Fédération GraphQL ?
La Fédération GraphQL est une architecture puissante qui vous permet de construire une API GraphQL unique et unifiée à partir de plusieurs services GraphQL sous-jacents (représentant souvent des microservices). Elle permet aux développeurs d'interroger des données à travers différents services comme s'il s'agissait d'un seul graphe, simplifiant l'expérience client et réduisant le besoin d'une logique d'orchestration complexe cÎté client.
Il existe deux approches principales de la Fédération GraphQL :
- Schema Stitching : Cela consiste Ă combiner plusieurs schĂ©mas GraphQL en un seul schĂ©ma unifiĂ© au niveau de la passerelle. C'est une approche plus ancienne qui s'appuie sur des bibliothĂšques pour gĂ©rer la combinaison des schĂ©mas et la dĂ©lĂ©gation des requĂȘtes.
- FĂ©dĂ©ration Apollo : C'est une approche plus rĂ©cente et robuste qui utilise un langage de schĂ©ma dĂ©claratif et un planificateur de requĂȘtes dĂ©diĂ© pour gĂ©rer le processus de fĂ©dĂ©ration. Elle offre des fonctionnalitĂ©s avancĂ©es comme les extensions de type, les directives de clĂ© et le traçage distribuĂ©.
Cet article se concentre sur le Schema Stitching, explorant ses concepts, ses avantages, ses limites et sa mise en Ćuvre pratique.
Comprendre le Schema Stitching
Le Schema Stitching est le processus de fusion de plusieurs schĂ©mas GraphQL en un seul schĂ©ma cohĂ©rent. Ce schĂ©ma unifiĂ© agit comme une façade, cachant la complexitĂ© des services sous-jacents au client. Lorsqu'un client fait une requĂȘte au schĂ©ma fusionnĂ©, la passerelle achemine intelligemment la requĂȘte vers le(s) service(s) sous-jacent(s) appropriĂ©(s), rĂ©cupĂšre les donnĂ©es et combine les rĂ©sultats avant de les renvoyer au client.
Imaginez la chose suivante : vous avez plusieurs restaurants (services) spécialisés chacun dans des cuisines différentes. Le Schema Stitching est comme un menu universel qui combine tous les plats de chaque restaurant. Lorsqu'un client passe une commande à partir du menu universel, la commande est intelligemment acheminée vers les cuisines des restaurants appropriés, la nourriture est préparée, puis combinée en une seule livraison pour le client.
Concepts Clés du Schema Stitching
- Schémas Distants : Ce sont les schémas GraphQL individuels de chaque service sous-jacent. Chaque service expose son propre schéma, qui définit les données et les opérations qu'il fournit.
- Passerelle : La passerelle est le composant central chargĂ© de fusionner les schĂ©mas distants et d'exposer le schĂ©ma unifiĂ© au client. Elle reçoit les requĂȘtes des clients, les achemine vers les services appropriĂ©s et combine les rĂ©sultats.
- Fusion de Schémas : C'est le processus de combinaison des schémas distants en un seul schéma. Cela implique souvent de renommer les types et les champs pour éviter les conflits et de définir des relations entre les types de différents schémas.
- DĂ©lĂ©gation de RequĂȘtes : Lorsqu'un client fait une requĂȘte au schĂ©ma fusionnĂ©, la passerelle doit dĂ©lĂ©guer la requĂȘte au(x) service(s) sous-jacent(s) appropriĂ©(s) pour rĂ©cupĂ©rer les donnĂ©es. Cela implique de traduire la requĂȘte du client en une requĂȘte comprĂ©hensible par le service distant.
- AgrĂ©gation des RĂ©sultats : AprĂšs que la passerelle a rĂ©cupĂ©rĂ© les donnĂ©es des services sous-jacents, elle doit combiner les rĂ©sultats en une seule rĂ©ponse qui peut ĂȘtre renvoyĂ©e au client. Cela implique souvent de transformer les donnĂ©es pour qu'elles correspondent Ă la structure du schĂ©ma fusionnĂ©.
Avantages du Schema Stitching
Le Schema Stitching offre plusieurs avantages convaincants pour les organisations qui adoptent une architecture de microservices :
- API Unifiée : Fournit une API unique et cohérente pour les clients, simplifiant l'accÚs aux données et réduisant le besoin pour les clients d'interagir directement avec plusieurs services. Cela se traduit par une expérience de développement plus propre et plus intuitive.
- Complexité CÎté Client Réduite : Les clients n'ont besoin d'interagir qu'avec le schéma unifié, ce qui les protÚge des complexités de l'architecture de microservices sous-jacente. Cela simplifie le développement cÎté client et réduit la quantité de code requise sur le client.
- ScalabilitĂ© Accrue : Permet de faire Ă©voluer les services individuels indĂ©pendamment en fonction de leurs besoins spĂ©cifiques. Cela amĂ©liore la scalabilitĂ© et la rĂ©silience globales du systĂšme. Par exemple, un service utilisateur subissant une charge Ă©levĂ©e peut ĂȘtre mis Ă l'Ă©chelle sans affecter d'autres services comme le catalogue de produits.
- Maintenabilité Améliorée : Favorise la modularité et la séparation des préoccupations, ce qui facilite la maintenance et l'évolution des services individuels. Les modifications apportées à un service sont moins susceptibles d'avoir un impact sur d'autres services.
- Adoption Graduelle : Peut ĂȘtre mis en Ćuvre de maniĂšre incrĂ©mentielle, vous permettant de migrer progressivement d'une architecture monolithique Ă une architecture de microservices. Vous pouvez commencer par fusionner des API existantes, puis dĂ©composer progressivement le monolithe en services plus petits.
Limites du Schema Stitching
Bien que le Schema Stitching offre de nombreux avantages, il est important d'ĂȘtre conscient de ses limites :
- ComplexitĂ© : La mise en Ćuvre et la gestion du schema stitching peuvent ĂȘtre complexes, en particulier dans les systĂšmes vastes et complexes. Une planification et une conception minutieuses sont essentielles.
- Surcharge de Performance : La passerelle introduit une certaine surcharge de performance en raison de la couche d'indirection supplĂ©mentaire et de la nĂ©cessitĂ© de dĂ©lĂ©guer les requĂȘtes et d'agrĂ©ger les rĂ©sultats. Une optimisation minutieuse est cruciale pour minimiser cette surcharge.
- Conflits de SchĂ©mas : Des conflits peuvent survenir lors de la fusion de schĂ©mas de diffĂ©rents services, surtout s'ils utilisent les mĂȘmes noms de type ou de champ. Cela nĂ©cessite une conception de schĂ©ma soignĂ©e et potentiellement le renommage de types et de champs.
- Fonctionnalités Avancées Limitées : Comparé à la Fédération Apollo, le Schema Stitching manque de certaines fonctionnalités avancées comme les extensions de type et les directives de clé, ce qui peut rendre plus difficile la gestion des relations entre les types de différents schémas.
- Maturité de l'Outillage : L'outillage et l'écosystÚme autour du Schema Stitching ne sont pas aussi matures que ceux de la Fédération Apollo. Cela peut rendre le débogage et la résolution des problÚmes plus difficiles.
Mise en Ćuvre Pratique du Schema Stitching
Voyons un exemple simplifiĂ© de mise en Ćuvre du Schema Stitching en utilisant Node.js et la bibliothĂšque graphql-tools (un choix populaire pour le schema stitching). Cet exemple implique deux microservices : un Service Utilisateur et un Service Produit.
1. Définir les Schémas Distants
D'abord, définissez les schémas GraphQL pour chacun des services distants.
Service Utilisateur (user-service.js):
const { buildSchema } = require('graphql');
const userSchema = buildSchema(`
type User {
id: ID!
name: String
email: String
}
type Query {
user(id: ID!): User
}
`);
const users = [
{ id: '1', name: 'Alice Smith', email: 'alice@example.com' },
{ id: '2', name: 'Bob Johnson', email: 'bob@example.com' },
];
const userRoot = {
user: (args) => users.find(user => user.id === args.id),
};
module.exports = {
schema: userSchema,
rootValue: userRoot,
};
Service Produit (product-service.js):
const { buildSchema } = require('graphql');
const productSchema = buildSchema(`
type Product {
id: ID!
name: String
price: Float
userId: ID! # Clé étrangÚre vers le Service Utilisateur
}
type Query {
product(id: ID!): Product
}
`);
const products = [
{ id: '101', name: 'Laptop', price: 1200, userId: '1' },
{ id: '102', name: 'Smartphone', price: 800, userId: '2' },
];
const productRoot = {
product: (args) => products.find(product => product.id === args.id),
};
module.exports = {
schema: productSchema,
rootValue: productRoot,
};
2. Créer le Service de Passerelle
Maintenant, créez le service de passerelle qui fusionnera les deux schémas.
Service de Passerelle (gateway.js):
const { stitchSchemas } = require('@graphql-tools/stitch');
const { makeRemoteExecutableSchema } = require('@graphql-tools/wrap');
const { graphqlHTTP } = require('express-graphql');
const express = require('express');
const { introspectSchema } = require('@graphql-tools/wrap');
const { printSchema } = require('graphql');
const fetch = require('node-fetch');
async function createRemoteSchema(uri) {
const fetcher = async (params) => {
const response = await fetch(uri, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
});
return response.json();
};
const schema = await introspectSchema(fetcher);
return makeRemoteExecutableSchema({
schema,
fetcher,
});
}
async function main() {
const userSchema = await createRemoteSchema('http://localhost:4001/graphql');
const productSchema = await createRemoteSchema('http://localhost:4002/graphql');
const stitchedSchema = stitchSchemas({
subschemas: [
{ schema: userSchema },
{ schema: productSchema },
],
typeDefs: `
extend type Product {
user: User
}
`,
resolvers: {
Product: {
user: {
selectionSet: `{ userId }`,
resolve(product, args, context, info) {
return info.mergeInfo.delegateToSchema({
schema: userSchema,
operation: 'query',
fieldName: 'user',
args: {
id: product.userId,
},
context,
info,
});
},
},
},
},
});
const app = express();
app.use('/graphql', graphqlHTTP({
schema: stitchedSchema,
graphiql: true,
}));
app.listen(4000, () => console.log('Serveur de passerelle en cours d'exécution sur http://localhost:4000/graphql'));
}
main().catch(console.error);
3. Exécuter les Services
Vous devrez exécuter le Service Utilisateur et le Service Produit sur des ports différents. Par exemple :
Service Utilisateur (port 4001):
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./user-service');
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: rootValue,
graphiql: true,
}));
app.listen(4001, () => console.log('Service utilisateur en cours d'exécution sur http://localhost:4001/graphql'));
Service Produit (port 4002):
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./product-service');
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: rootValue,
graphiql: true,
}));
app.listen(4002, () => console.log('Service produit en cours d'exécution sur http://localhost:4002/graphql'));
4. Interroger le Schéma Fusionné
Vous pouvez maintenant interroger le schĂ©ma fusionnĂ© via la passerelle (exĂ©cutĂ©e sur le port 4000). Vous pouvez exĂ©cuter une requĂȘte comme celle-ci :
query {
product(id: "101") {
id
name
price
user {
id
name
email
}
}
}
Cette requĂȘte rĂ©cupĂšre le produit avec l'ID "101" et rĂ©cupĂšre Ă©galement l'utilisateur associĂ© du Service Utilisateur, dĂ©montrant comment le Schema Stitching vous permet d'interroger des donnĂ©es sur plusieurs services en une seule requĂȘte.
Techniques Avancées de Schema Stitching
Au-delĂ de l'exemple de base, voici quelques techniques avancĂ©es qui peuvent ĂȘtre utilisĂ©es pour amĂ©liorer votre implĂ©mentation de Schema Stitching :
- DĂ©lĂ©gation de SchĂ©ma : Cela vous permet de dĂ©lĂ©guer des parties d'une requĂȘte Ă diffĂ©rents services en fonction des donnĂ©es demandĂ©es. Par exemple, vous pouvez dĂ©lĂ©guer la rĂ©solution d'un type `User` au Service Utilisateur et la rĂ©solution d'un type `Product` au Service Produit.
- Transformation de SchĂ©ma : Cela consiste Ă modifier le schĂ©ma d'un service distant avant qu'il ne soit fusionnĂ© dans le schĂ©ma unifiĂ©. Cela peut ĂȘtre utile pour renommer des types et des champs, ajouter de nouveaux champs ou supprimer des champs existants.
- Résolveurs Personnalisés : Vous pouvez définir des résolveurs personnalisés dans la passerelle pour gérer des transformations de données complexes ou pour récupérer des données de plusieurs services et les combiner en un seul résultat.
- Partage de Contexte : Il est souvent nĂ©cessaire de partager des informations de contexte entre la passerelle et les services distants, comme des jetons d'authentification ou des ID utilisateur. Ceci peut ĂȘtre rĂ©alisĂ© en passant les informations de contexte dans le cadre du processus de dĂ©lĂ©gation de requĂȘte.
- Gestion des Erreurs : Mettez en Ćuvre une gestion robuste des erreurs pour traiter gracieusement les erreurs qui se produisent dans les services distants. Cela peut impliquer la journalisation des erreurs, le renvoi de messages d'erreur conviviaux ou la relance des requĂȘtes Ă©chouĂ©es.
Choisir entre le Schema Stitching et la Fédération Apollo
Bien que le Schema Stitching soit une option viable pour la Fédération GraphQL, la Fédération Apollo est devenue le choix le plus populaire en raison de ses fonctionnalités avancées et de son expérience de développement améliorée. Voici une comparaison des deux approches :
| Fonctionnalité | Schema Stitching | Fédération Apollo |
|---|---|---|
| Définition du Schéma | Utilise le langage de schéma GraphQL existant | Utilise un langage de schéma déclaratif avec des directives |
| Planification des RequĂȘtes | NĂ©cessite une dĂ©lĂ©gation de requĂȘte manuelle | Planification automatique des requĂȘtes par la passerelle Apollo |
| Extensions de Type | Support limité | Support intégré pour les extensions de type |
| Directives de Clé | Non supporté | Utilise la directive @key pour identifier les entités |
| Traçage Distribué | Nécessite une implémentation manuelle | Support intégré pour le traçage distribué |
| Outillage et ĂcosystĂšme | Outillage moins mature | Outillage plus mature et une grande communautĂ© |
| ComplexitĂ© | Peut ĂȘtre complexe Ă gĂ©rer dans de grands systĂšmes | Conçu pour les systĂšmes vastes et complexes |
Quand choisir le Schema Stitching :
- Vous avez des services GraphQL existants et souhaitez les combiner rapidement.
- Vous avez besoin d'une solution de fédération simple et ne nécessitez pas de fonctionnalités avancées.
- Vous avez des ressources limitées et voulez éviter la surcharge liée à la mise en place de la Fédération Apollo.
Quand choisir la Fédération Apollo :
- Vous construisez un systÚme vaste et complexe avec plusieurs équipes et services.
- Vous avez besoin de fonctionnalités avancées comme les extensions de type, les directives de clé et le traçage distribué.
- Vous voulez une solution de fédération plus robuste et scalable.
- Vous préférez une approche de la fédération plus déclarative et automatisée.
Exemples Concrets et Cas d'Usage
Voici quelques exemples concrets de la maniĂšre dont la FĂ©dĂ©ration GraphQL, y compris le Schema Stitching, peut ĂȘtre utilisĂ©e :
- Plateforme E-commerce : Une plateforme e-commerce pourrait utiliser la Fédération GraphQL pour combiner des données de plusieurs services, tels qu'un service de catalogue de produits, un service utilisateur, un service de commandes et un service de paiement. Cela permet aux clients de récupérer facilement toutes les informations dont ils ont besoin pour afficher les détails des produits, les profils utilisateur, l'historique des commandes et les informations de paiement.
- Plateforme de Médias Sociaux : Une plateforme de médias sociaux pourrait utiliser la Fédération GraphQL pour combiner des données de services qui gÚrent les profils utilisateur, les publications, les commentaires et les "j'aime". Cela permet aux clients de récupérer efficacement toutes les informations nécessaires pour afficher le profil d'un utilisateur, ses publications, ainsi que les commentaires et les "j'aime" associés à ces publications.
- Application de Services Financiers : Une application de services financiers pourrait utiliser la Fédération GraphQL pour combiner des données de services qui gÚrent les comptes, les transactions et les investissements. Cela permet aux clients de récupérer facilement toutes les informations dont ils ont besoin pour afficher les soldes des comptes, l'historique des transactions et les portefeuilles d'investissement.
- SystÚme de Gestion de Contenu (CMS) : Un CMS peut tirer parti de la Fédération GraphQL pour intégrer des données de diverses sources comme des articles, des images, des vidéos et du contenu généré par les utilisateurs. Cela permet une API unifiée pour récupérer tout le contenu lié à un sujet ou un auteur spécifique.
- Application de Santé : Intégrer les données des patients de différents systÚmes comme les dossiers de santé électroniques (DSE), les résultats de laboratoire et la planification de rendez-vous. Cela offre aux médecins un point d'accÚs unique à des informations complÚtes sur les patients.
Meilleures Pratiques pour le Schema Stitching
Pour garantir une implémentation réussie du Schema Stitching, suivez ces meilleures pratiques :
- Planifiez votre schéma avec soin : Avant de commencer à fusionner des schémas, planifiez soigneusement la structure du schéma unifié. Cela inclut la définition des relations entre les types de différents schémas, le renommage des types et des champs pour éviter les conflits, et la prise en compte des modÚles d'accÚs aux données globaux.
- Utilisez des conventions de nommage cohérentes : Adoptez des conventions de nommage cohérentes pour les types, les champs et les opérations dans tous les services. Cela aidera à éviter les conflits et facilitera la compréhension du schéma unifié.
- Documentez votre schéma : Documentez minutieusement le schéma unifié, y compris les descriptions des types, des champs et des opérations. Cela facilitera la compréhension et l'utilisation du schéma par les développeurs.
- Surveillez les performances : Surveillez les performances de la passerelle et des services distants pour identifier et rĂ©soudre les goulots d'Ă©tranglement de performance. Utilisez des outils comme le traçage distribuĂ© pour suivre les requĂȘtes Ă travers plusieurs services.
- Mettez en Ćuvre la sĂ©curitĂ© : Mettez en Ćuvre des mesures de sĂ©curitĂ© appropriĂ©es pour protĂ©ger la passerelle et les services distants contre les accĂšs non autorisĂ©s. Cela peut impliquer l'utilisation de mĂ©canismes d'authentification et d'autorisation, ainsi que la validation des entrĂ©es et l'encodage des sorties.
- Versionnez votre schéma : Au fur et à mesure que vous faites évoluer vos schémas, versionnez-les de maniÚre appropriée pour garantir que les clients puissent continuer à utiliser les anciennes versions du schéma sans interruption. Cela aidera à éviter les changements cassants et à assurer la rétrocompatibilité.
- Automatisez le dĂ©ploiement : Automatisez le dĂ©ploiement de la passerelle et des services distants pour garantir que les modifications peuvent ĂȘtre dĂ©ployĂ©es rapidement et de maniĂšre fiable. Cela aidera Ă rĂ©duire le risque d'erreurs et Ă amĂ©liorer l'agilitĂ© globale du systĂšme.
Conclusion
La FĂ©dĂ©ration GraphQL avec le Schema Stitching offre une approche puissante pour construire des API unifiĂ©es Ă partir de plusieurs services dans une architecture de microservices. En comprenant ses concepts fondamentaux, ses avantages, ses limites et ses techniques de mise en Ćuvre, vous pouvez tirer parti du Schema Stitching pour simplifier l'accĂšs aux donnĂ©es, amĂ©liorer la scalabilitĂ© et renforcer la maintenabilitĂ©. Bien que la FĂ©dĂ©ration Apollo soit apparue comme une solution plus avancĂ©e, le Schema Stitching reste une option viable pour des scĂ©narios plus simples ou lors de l'intĂ©gration de services GraphQL existants. Examinez attentivement vos besoins et exigences spĂ©cifiques pour choisir la meilleure approche pour votre organisation.