Français

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 :

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

Avantages du Schema Stitching

Le Schema Stitching offre plusieurs avantages convaincants pour les organisations qui adoptent une architecture de microservices :

Limites du Schema Stitching

Bien que le Schema Stitching offre de nombreux avantages, il est important d'être conscient de ses limites :

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 :

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 :

Quand choisir la Fédération Apollo :

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 :

Meilleures Pratiques pour le Schema Stitching

Pour garantir une implémentation réussie du Schema Stitching, suivez ces meilleures pratiques :

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.