Română

Eliberați puterea Federației GraphQL cu Schema Stitching. Aflați cum să construiți un API GraphQL unificat din mai multe servicii, îmbunătățind scalabilitatea și mentenabilitatea.

Federația GraphQL: Schema Stitching - Un Ghid Complet

În peisajul în continuă evoluție al dezvoltării aplicațiilor moderne, necesitatea unor arhitecturi scalabile și ușor de întreținut a devenit primordială. Microserviciile, cu modularitatea lor inerentă și capacitatea de a fi implementate independent, au apărut ca o soluție populară. Cu toate acestea, gestionarea a numeroase microservicii poate introduce complexități, în special atunci când vine vorba de expunerea unui API unificat către aplicațiile client. Aici intervin Federația GraphQL și, în mod specific, Schema Stitching.

Ce este Federația GraphQL?

Federația GraphQL este o arhitectură puternică ce vă permite să construiți un singur API GraphQL unificat din mai multe servicii GraphQL subiacente (reprezentând adesea microservicii). Aceasta le permite dezvoltatorilor să interogheze date din diferite servicii ca și cum ar fi un singur graf, simplificând experiența clientului și reducând necesitatea unei logici complexe de orchestrare pe partea clientului.

Există două abordări principale ale Federației GraphQL:

Acest articol se concentrează pe Schema Stitching, explorând conceptele, beneficiile, limitările și implementarea sa practică.

Înțelegerea Conceptului de Schema Stitching

Schema Stitching este procesul de fuzionare a mai multor scheme GraphQL într-o singură schemă, coezivă. Această schemă unificată acționează ca o fațadă, ascunzând complexitatea serviciilor subiacente de client. Când un client face o cerere către schema combinată, gateway-ul direcționează inteligent cererea către serviciul sau serviciile subiacente corespunzătoare, preia datele și combină rezultatele înainte de a le returna clientului.

Gândiți-vă la asta în felul următor: Aveți mai multe restaurante (servicii), fiecare specializat în bucătării diferite. Schema Stitching este ca un meniu universal care combină toate preparatele de la fiecare restaurant. Când un client comandă din meniul universal, comanda este direcționată inteligent către bucătăriile restaurantelor corespunzătoare, mâncarea este preparată și apoi combinată într-o singură livrare pentru client.

Concepte Cheie în Schema Stitching

Beneficiile Schema Stitching

Schema Stitching oferă câteva beneficii convingătoare pentru organizațiile care adoptă o arhitectură de microservicii:

Limitările Schema Stitching

Deși Schema Stitching oferă numeroase avantaje, este important să fiți conștienți de limitările sale:

Implementare Practică a Schema Stitching

Să parcurgem un exemplu simplificat despre cum se implementează Schema Stitching folosind Node.js și biblioteca graphql-tools (o alegere populară pentru combinarea schemelor). Acest exemplu implică două microservicii: un Serviciu de Utilizatori (User Service) și un Serviciu de Produse (Product Service).

1. Definiți Schemele Remote

Mai întâi, definiți schemele GraphQL pentru fiecare dintre serviciile remote.

Serviciul de Utilizatori (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,
};

Serviciul de Produse (product-service.js):


const { buildSchema } = require('graphql');

const productSchema = buildSchema(`
  type Product {
    id: ID!
    name: String
    price: Float
    userId: ID!  # Foreign key to User Service
  }

  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. Creați Serviciul Gateway

Acum, creați serviciul gateway care va combina cele două scheme.

Serviciul Gateway (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('Gateway server running on http://localhost:4000/graphql'));
}

main().catch(console.error);

3. Rulați Serviciile

Va trebui să rulați Serviciul de Utilizatori și Serviciul de Produse pe porturi diferite. De exemplu:

Serviciul de Utilizatori (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('User service running on http://localhost:4001/graphql'));

Serviciul de Produse (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('Product service running on http://localhost:4002/graphql'));

4. Interogați Schema Combinată

Acum puteți interoga schema combinată prin intermediul gateway-ului (care rulează pe portul 4000). Puteți rula o interogare ca aceasta:


query {
  product(id: "101") {
    id
    name
    price
    user {
      id
      name
      email
    }
  }
}

Această interogare preia produsul cu ID-ul "101" și, de asemenea, aduce utilizatorul asociat din Serviciul de Utilizatori, demonstrând cum Schema Stitching vă permite să interogați date din mai multe servicii într-o singură cerere.

Tehnici Avansate de Schema Stitching

Dincolo de exemplul de bază, iată câteva tehnici avansate care pot fi folosite pentru a vă îmbunătăți implementarea Schema Stitching:

Alegerea între Schema Stitching și Apollo Federation

Deși Schema Stitching este o opțiune viabilă pentru Federația GraphQL, Apollo Federation a devenit alegerea mai populară datorită funcționalităților sale avansate și experienței îmbunătățite pentru dezvoltatori. Iată o comparație a celor două abordări:

Caracteristică Schema Stitching Apollo Federation
Definirea Schemei Utilizează limbajul de schemă GraphQL existent Utilizează un limbaj de schemă declarativ cu directive
Planificarea Interogării Necesită delegare manuală a interogărilor Planificare automată a interogărilor de către Apollo Gateway
Extensii de Tip Suport limitat Suport integrat pentru extensii de tip
Directive Cheie Nu este suportat Utilizează directiva @key pentru a identifica entitățile
Urmărire Distribuită Necesită implementare manuală Suport integrat pentru urmărire distribuită
Unelte și Ecosistem Unelte mai puțin mature Unelte mai mature și o comunitate mare
Complexitate Poate fi complex de gestionat în sisteme mari Proiectat pentru sisteme mari și complexe

Când să alegeți Schema Stitching:

Când să alegeți Apollo Federation:

Exemple din Lumea Reală și Cazuri de Utilizare

Iată câteva exemple din lumea reală despre cum poate fi utilizată Federația GraphQL, inclusiv Schema Stitching:

Cele mai Bune Practici pentru Schema Stitching

Pentru a asigura o implementare de succes a Schema Stitching, urmați aceste bune practici:

Concluzie

Federația GraphQL cu Schema Stitching oferă o abordare puternică pentru construirea de API-uri unificate din mai multe servicii într-o arhitectură de microservicii. Înțelegând conceptele sale de bază, beneficiile, limitările și tehnicile de implementare, puteți valorifica Schema Stitching pentru a simplifica accesul la date, a îmbunătăți scalabilitatea și a spori mentenabilitatea. Deși Apollo Federation a apărut ca o soluție mai avansată, Schema Stitching rămâne o opțiune viabilă pentru scenarii mai simple sau la integrarea serviciilor GraphQL existente. Luați în considerare cu atenție nevoile și cerințele specifice pentru a alege cea mai bună abordare pentru organizația dumneavoastră.