Slovenščina

Odkrijte moč federacije GraphQL z združevanjem shem. Naučite se zgraditi enoten API GraphQL iz več storitev ter izboljšati razširljivost in vzdržljivost.

Federacija GraphQL: Združevanje shem (Schema Stitching) - Celovit vodnik

V nenehno razvijajočem se okolju sodobnega razvoja aplikacij je potreba po razširljivih in vzdržljivih arhitekturah postala ključnega pomena. Mikrostoritve so s svojo inherentno modularnostjo in neodvisno možnostjo uvajanja postale priljubljena rešitev. Vendar pa lahko upravljanje številnih mikrostoritev povzroči zaplete, zlasti ko gre za izpostavitev enotnega API-ja odjemalskim aplikacijam. Tu nastopi federacija GraphQL, natančneje združevanje shem (Schema Stitching).

Kaj je federacija GraphQL?

Federacija GraphQL je zmogljiva arhitektura, ki vam omogoča izgradnjo enega samega, enotnega API-ja GraphQL iz več osnovnih storitev GraphQL (ki pogosto predstavljajo mikrostoritve). Razvijalcem omogoča poizvedovanje po podatkih v različnih storitvah, kot da bi šlo za en sam graf, kar poenostavlja izkušnjo odjemalca in zmanjšuje potrebo po zapleteni logiki orkestracije na strani odjemalca.

Obstajata dva glavna pristopa k federaciji GraphQL:

Ta članek se osredotoča na združevanje shem, raziskuje njegove koncepte, prednosti, omejitve in praktično implementacijo.

Razumevanje združevanja shem

Združevanje shem je postopek združevanja več shem GraphQL v eno samo, kohezivno shemo. Ta enotna shema deluje kot fasada, ki pred odjemalcem skriva kompleksnost osnovnih storitev. Ko odjemalec pošlje zahtevo na združeno shemo, prehod inteligentno usmeri zahtevo do ustrezne osnovne storitve (ali storitev), pridobi podatke in združi rezultate, preden jih vrne odjemalcu.

Predstavljajte si to takole: Imate več restavracij (storitev), od katerih je vsaka specializirana za različne kuhinje. Združevanje shem je kot univerzalni meni, ki združuje vse jedi iz vsake restavracije. Ko stranka (odjemalec) naroči z univerzalnega menija, je naročilo inteligentno usmerjeno v ustrezne kuhinje restavracij, hrana je pripravljena in nato združena v eno samo dostavo za stranko.

Ključni koncepti pri združevanju shem

Prednosti združevanja shem

Združevanje shem ponuja več prepričljivih prednosti za organizacije, ki uporabljajo arhitekturo mikrostoritev:

Omejitve združevanja shem

Čeprav združevanje shem ponuja številne prednosti, se je pomembno zavedati njegovih omejitev:

Praktična implementacija združevanja shem

Poglejmo si poenostavljen primer, kako implementirati združevanje shem z uporabo Node.js in knjižnice graphql-tools (priljubljena izbira za združevanje shem). Ta primer vključuje dve mikrostoritvi: storitev za uporabnike in storitev za izdelke.

1. Definirajte oddaljene sheme

Najprej definirajte sheme GraphQL za vsako od oddaljenih storitev.

Storitev za uporabnike (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,
};

Storitev za izdelke (product-service.js):


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

const productSchema = buildSchema(`
  type Product {
    id: ID!
    name: String
    price: Float
    userId: ID!  // Tuji ključ do storitve za uporabnike
  }

  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. Ustvarite storitev prehoda (Gateway)

Sedaj ustvarite storitev prehoda, ki bo združila obe shemi.

Storitev prehoda (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('Strežnik prehoda teče na http://localhost:4000/graphql'));
}

main().catch(console.error);

3. Zaženite storitve

Storitev za uporabnike in storitev za izdelke morate zagnati na različnih vratih. Na primer:

Storitev za uporabnike (vrata 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('Storitev za uporabnike teče na http://localhost:4001/graphql'));

Storitev za izdelke (vrata 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('Storitev za izdelke teče na http://localhost:4002/graphql'));

4. Pošljite poizvedbo na združeno shemo

Sedaj lahko pošljete poizvedbo na združeno shemo prek prehoda (ki teče na vratih 4000). Poženete lahko poizvedbo, kot je ta:


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

Ta poizvedba pridobi izdelek z ID-jem "101" in hkrati pridobi povezanega uporabnika iz storitve za uporabnike, kar prikazuje, kako združevanje shem omogoča poizvedovanje po podatkih v več storitvah z eno samo zahtevo.

Napredne tehnike združevanja shem

Poleg osnovnega primera so tu še nekatere napredne tehnike, ki jih lahko uporabite za izboljšanje vaše implementacije združevanja shem:

Izbira med združevanjem shem in federacijo Apollo

Čeprav je združevanje shem izvedljiva možnost za federacijo GraphQL, je federacija Apollo postala bolj priljubljena izbira zaradi svojih naprednih funkcij in izboljšane izkušnje za razvijalce. Tukaj je primerjava obeh pristopov:

Značilnost Združevanje shem Federacija Apollo
Definicija sheme Uporablja obstoječi jezik shem GraphQL Uporablja deklarativni jezik shem z direktivami
Načrtovanje poizvedb Zahteva ročno delegiranje poizvedb Samodejno načrtovanje poizvedb s prehodom Apollo
Razširitve tipov Omejena podpora Vgrajena podpora za razširitve tipov
Ključne direktive Ni podprto Uporablja direktivo @key za identifikacijo entitet
Porazdeljeno sledenje Zahteva ročno implementacijo Vgrajena podpora za porazdeljeno sledenje
Orodja in ekosistem Manj zrela orodja Bolj zrela orodja in velika skupnost
Kompleksnost Upravljanje v velikih sistemih je lahko kompleksno Zasnovana za velike in kompleksne sisteme

Kdaj izbrati združevanje shem:

Kdaj izbrati federacijo Apollo:

Primeri iz prakse in primeri uporabe

Tukaj je nekaj primerov iz prakse, kako se lahko uporablja federacija GraphQL, vključno z združevanjem shem:

Najboljše prakse za združevanje shem

Da bi zagotovili uspešno implementacijo združevanja shem, upoštevajte te najboljše prakse:

Zaključek

Federacija GraphQL z združevanjem shem ponuja zmogljiv pristop k izgradnji enotnih API-jev iz več storitev v arhitekturi mikrostoritev. Z razumevanjem njenih temeljnih konceptov, prednosti, omejitev in tehnik implementacije lahko izkoristite združevanje shem za poenostavitev dostopa do podatkov, izboljšanje razširljivosti in povečanje vzdržljivosti. Čeprav se je federacija Apollo pojavila kot naprednejša rešitev, združevanje shem ostaja izvedljiva možnost za enostavnejše scenarije ali pri integraciji obstoječih storitev GraphQL. Skrbno pretehtajte svoje specifične potrebe in zahteve, da izberete najboljši pristop za svojo organizacijo.