Español

Desbloquee el poder de la Federación GraphQL con Schema Stitching. Aprenda a construir una API GraphQL unificada a partir de múltiples servicios, mejorando la escalabilidad y la mantenibilidad.

Federación GraphQL: Schema Stitching - Una Guía Completa

En el panorama en constante evolución del desarrollo de aplicaciones modernas, la necesidad de arquitecturas escalables y mantenibles se ha vuelto primordial. Los microservicios, con su modularidad inherente y su capacidad de despliegue independiente, han surgido como una solución popular. Sin embargo, gestionar numerosos microservicios puede introducir complejidades, especialmente cuando se trata de exponer una API unificada a las aplicaciones cliente. Aquí es donde entran en juego la Federación GraphQL y, específicamente, el Schema Stitching.

¿Qué es la Federación GraphQL?

La Federación GraphQL es una arquitectura potente que le permite construir una única API GraphQL unificada a partir de múltiples servicios GraphQL subyacentes (que a menudo representan microservicios). Permite a los desarrolladores consultar datos a través de diferentes servicios como si fuera un único grafo, simplificando la experiencia del cliente y reduciendo la necesidad de una lógica de orquestación compleja en el lado del cliente.

Existen dos enfoques principales para la Federación GraphQL:

Este artículo se centra en el Schema Stitching, explorando sus conceptos, beneficios, limitaciones e implementación práctica.

Entendiendo el Schema Stitching

El Schema Stitching es el proceso de fusionar múltiples esquemas GraphQL en un único esquema cohesivo. Este esquema unificado actúa como una fachada, ocultando la complejidad de los servicios subyacentes al cliente. Cuando un cliente realiza una solicitud al esquema "cosido" (stitched), la pasarela enruta inteligentemente la solicitud al servicio o servicios subyacentes apropiados, recupera los datos y combina los resultados antes de devolverlos al cliente.

Piénselo de esta manera: tiene varios restaurantes (servicios), cada uno especializado en diferentes cocinas. El Schema Stitching es como un menú universal que combina todos los platos de cada restaurante. Cuando un cliente (cliente) ordena del menú universal, el pedido se enruta inteligentemente a las cocinas de los restaurantes apropiados, la comida se prepara y luego se combina en una sola entrega para el cliente.

Conceptos Clave en Schema Stitching

Beneficios del Schema Stitching

El Schema Stitching ofrece varios beneficios convincentes para las organizaciones que adoptan una arquitectura de microservicios:

Limitaciones del Schema Stitching

Aunque el Schema Stitching ofrece numerosas ventajas, es importante ser consciente de sus limitaciones:

Implementación Práctica de Schema Stitching

Veamos un ejemplo simplificado de cómo implementar Schema Stitching usando Node.js y la biblioteca graphql-tools (una opción popular para "schema stitching"). Este ejemplo involucra dos microservicios: un Servicio de Usuarios y un Servicio de Productos.

1. Definir los Esquemas Remotos

Primero, defina los esquemas GraphQL para cada uno de los servicios remotos.

Servicio de Usuarios (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,
};

Servicio de Productos (product-service.js):


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

const productSchema = buildSchema(`
  type Product {
    id: ID!
    name: String
    price: Float
    userId: ID!  # Clave foránea al Servicio de Usuarios
  }

  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. Crear el Servicio de Pasarela (Gateway)

Ahora, cree el servicio de pasarela que "coserá" los dos esquemas.

Servicio de Pasarela (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('Servidor de pasarela ejecutándose en http://localhost:4000/graphql'));
}

main().catch(console.error);

3. Ejecutar los Servicios

Tendrá que ejecutar el Servicio de Usuarios y el Servicio de Productos en diferentes puertos. Por ejemplo:

Servicio de Usuarios (puerto 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('Servicio de usuarios ejecutándose en http://localhost:4001/graphql'));

Servicio de Productos (puerto 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('Servicio de productos ejecutándose en http://localhost:4002/graphql'));

4. Consultar el Esquema "Cosido"

Ahora puede consultar el esquema "cosido" a través de la pasarela (ejecutándose en el puerto 4000). Puede ejecutar una consulta como esta:


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

Esta consulta recupera el producto con ID "101" y también obtiene el usuario asociado del Servicio de Usuarios, demostrando cómo el Schema Stitching le permite consultar datos de múltiples servicios en una sola solicitud.

Técnicas Avanzadas de Schema Stitching

Más allá del ejemplo básico, aquí hay algunas técnicas avanzadas que se pueden usar para mejorar su implementación de Schema Stitching:

Elegir entre Schema Stitching y Apollo Federation

Aunque Schema Stitching es una opción viable para la Federación GraphQL, Apollo Federation se ha convertido en la opción más popular debido a sus características avanzadas y una mejor experiencia de desarrollador. Aquí hay una comparación de los dos enfoques:

Característica Schema Stitching Apollo Federation
Definición de Esquema Usa el lenguaje de esquema GraphQL existente Usa un lenguaje de esquema declarativo con directivas
Planificación de Consultas Requiere delegación manual de consultas Planificación automática de consultas por la Pasarela Apollo
Extensiones de Tipo Soporte limitado Soporte integrado para extensiones de tipo
Directivas de Clave No soportado Usa la directiva @key para identificar entidades
Seguimiento Distribuido Requiere implementación manual Soporte integrado para seguimiento distribuido
Herramientas y Ecosistema Herramientas menos maduras Herramientas más maduras y una gran comunidad
Complejidad Puede ser complejo de gestionar en sistemas grandes Diseñado para sistemas grandes y complejos

Cuándo elegir Schema Stitching:

Cuándo elegir Apollo Federation:

Ejemplos del Mundo Real y Casos de Uso

Aquí hay algunos ejemplos del mundo real de cómo se puede utilizar la Federación GraphQL, incluido el Schema Stitching:

Mejores Prácticas para Schema Stitching

Para garantizar una implementación exitosa de Schema Stitching, siga estas mejores prácticas:

Conclusión

La Federación GraphQL con Schema Stitching ofrece un enfoque potente para construir API unificadas a partir de múltiples servicios en una arquitectura de microservicios. Al comprender sus conceptos básicos, beneficios, limitaciones y técnicas de implementación, puede aprovechar el Schema Stitching para simplificar el acceso a los datos, mejorar la escalabilidad y aumentar la mantenibilidad. Aunque Apollo Federation ha surgido como una solución más avanzada, Schema Stitching sigue siendo una opción viable para escenarios más simples o al integrar servicios GraphQL existentes. Considere cuidadosamente sus necesidades y requisitos específicos para elegir el mejor enfoque para su organización.