Polski

Odkryj moc Federacji GraphQL dzięki Schema Stitching. Dowiedz się, jak budować zunifikowane API GraphQL z wielu usług, poprawiając skalowalność i łatwość utrzymania.

Federacja GraphQL: Schema Stitching - Kompleksowy przewodnik

W stale ewoluującym krajobrazie nowoczesnego tworzenia aplikacji potrzeba skalowalnych i łatwych w utrzymaniu architektur stała się najważniejsza. Mikrousługi, z ich wrodzoną modularnością i niezależnością wdrożeń, stały się popularnym rozwiązaniem. Jednak zarządzanie licznymi mikrousługami może wprowadzać komplikacje, zwłaszcza jeśli chodzi o udostępnianie zunifikowanego API aplikacjom klienckim. W tym miejscu do gry wchodzi Federacja GraphQL, a w szczególności Schema Stitching.

Czym jest Federacja GraphQL?

Federacja GraphQL to potężna architektura, która pozwala na budowę jednego, zunifikowanego API GraphQL z wielu bazowych usług GraphQL (często reprezentujących mikrousługi). Umożliwia ona deweloperom odpytywanie danych z różnych usług, jakby były jednym grafem, upraszczając doświadczenie klienta i redukując potrzebę skomplikowanej logiki orkiestracji po stronie klienta.

Istnieją dwa główne podejścia do Federacji GraphQL:

Ten artykuł koncentruje się na Schema Stitching, zgłębiając jego koncepcje, korzyści, ograniczenia i praktyczną implementację.

Zrozumienie Schema Stitching

Schema Stitching to proces łączenia wielu schematów GraphQL w jeden, spójny schemat. Ten zunifikowany schemat działa jak fasada, ukrywając złożoność bazowych usług przed klientem. Gdy klient wysyła żądanie do połączonego schematu, bramka inteligentnie przekierowuje żądanie do odpowiedniej usługi lub usług, pobiera dane i łączy wyniki przed zwróceniem ich do klienta.

Wyobraź to sobie w ten sposób: Masz wiele restauracji (usług), z których każda specjalizuje się w innej kuchni. Schema Stitching jest jak uniwersalne menu, które łączy wszystkie dania z każdej restauracji. Kiedy klient (klient) zamawia z uniwersalnego menu, zamówienie jest inteligentnie kierowane do odpowiednich kuchni restauracyjnych, jedzenie jest przygotowywane, a następnie łączone w jedną dostawę dla klienta.

Kluczowe pojęcia w Schema Stitching

Korzyści z Schema Stitching

Schema Stitching oferuje kilka istotnych korzyści dla organizacji wdrażających architekturę mikrousług:

Ograniczenia Schema Stitching

Mimo że Schema Stitching oferuje liczne zalety, ważne jest, aby być świadomym jego ograniczeń:

Praktyczna implementacja Schema Stitching

Przeanalizujmy uproszczony przykład implementacji Schema Stitching przy użyciu Node.js i biblioteki graphql-tools (popularny wybór do łączenia schematów). Ten przykład obejmuje dwie mikrousługi: usługę użytkownika i usługę produktu.

1. Zdefiniuj zdalne schematy

Najpierw zdefiniuj schematy GraphQL dla każdej ze zdalnych usług.

Usługa użytkownika (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,
};

Usługa produktu (product-service.js):


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

const productSchema = buildSchema(`
  type Product {
    id: ID!
    name: String
    price: Float
    userId: ID!  # Klucz obcy do usługi użytkownika
  }

  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. Utwórz usługę bramki (Gateway)

Teraz utwórz usługę bramki, która połączy oba schematy.

Usługa bramki (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. Uruchom usługi

Musisz uruchomić usługę użytkownika i usługę produktu na różnych portach. Na przykład:

Usługa użytkownika (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'));

Usługa produktu (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. Wykonaj zapytanie do połączonego schematu

Teraz możesz wykonywać zapytania do połączonego schematu za pośrednictwem bramki (działającej na porcie 4000). Możesz uruchomić zapytanie takie jak to:


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

To zapytanie pobiera produkt o ID "101", a także pobiera powiązanego użytkownika z usługi użytkownika, co pokazuje, jak Schema Stitching pozwala na odpytywanie danych z wielu usług w jednym żądaniu.

Zaawansowane techniki Schema Stitching

Oprócz podstawowego przykładu, oto kilka zaawansowanych technik, które można wykorzystać do ulepszenia implementacji Schema Stitching:

Wybór między Schema Stitching a Apollo Federation

Chociaż Schema Stitching jest realną opcją dla Federacji GraphQL, Apollo Federation stała się popularniejszym wyborem ze względu na zaawansowane funkcje i lepsze doświadczenie programistyczne. Oto porównanie obu podejść:

Cecha Schema Stitching Apollo Federation
Definicja schematu Używa istniejącego języka schematów GraphQL Używa deklaratywnego języka schematów z dyrektywami
Planowanie zapytań Wymaga ręcznego delegowania zapytań Automatyczne planowanie zapytań przez Apollo Gateway
Rozszerzenia typów Ograniczone wsparcie Wbudowane wsparcie dla rozszerzeń typów
Dyrektywy kluczy Brak wsparcia Używa dyrektywy @key do identyfikacji encji
Rozproszone śledzenie Wymaga ręcznej implementacji Wbudowane wsparcie dla rozproszonego śledzenia
Narzędzia i ekosystem Mniej dojrzałe narzędzia Bardziej dojrzałe narzędzia i duża społeczność
Złożoność Może być skomplikowane w zarządzaniu w dużych systemach Zaprojektowane dla dużych i złożonych systemów

Kiedy wybrać Schema Stitching:

Kiedy wybrać Apollo Federation:

Przykłady z życia wzięte i przypadki użycia

Oto kilka rzeczywistych przykładów wykorzystania Federacji GraphQL, w tym Schema Stitching:

Dobre praktyki dla Schema Stitching

Aby zapewnić udaną implementację Schema Stitching, postępuj zgodnie z tymi najlepszymi praktykami:

Podsumowanie

Federacja GraphQL z Schema Stitching oferuje potężne podejście do budowania zunifikowanych interfejsów API z wielu usług w architekturze mikrousług. Rozumiejąc jej podstawowe koncepcje, korzyści, ograniczenia i techniki implementacji, możesz wykorzystać Schema Stitching do uproszczenia dostępu do danych, poprawy skalowalności i zwiększenia łatwości utrzymania. Chociaż Apollo Federation stała się bardziej zaawansowanym rozwiązaniem, Schema Stitching pozostaje realną opcją dla prostszych scenariuszy lub przy integracji istniejących usług GraphQL. Starannie rozważ swoje specyficzne potrzeby i wymagania, aby wybrać najlepsze podejście dla swojej organizacji.