Atskleiskite GraphQL Federacijos galią su Schemos Sujungimu. Išmokite kurti vieningą GraphQL API iš kelių servisų, gerindami mastelį ir priežiūrą.
GraphQL Federacija: Schemos Sujungimas (Schema Stitching) - Išsamus Vadovas
Nuolat besikeičiančioje modernių programų kūrimo aplinkoje būtinybė turėti mastelį didinančias ir lengvai prižiūrimas architektūras tapo svarbiausia. Mikroservisai, pasižymintys moduliškumu ir nepriklausomu diegiamumu, tapo populiariu sprendimu. Tačiau daugybės mikroservisų valdymas gali sukelti sudėtingumų, ypač kai reikia pateikti vieningą API kliento aplikacijoms. Būtent čia į pagalbą ateina GraphQL Federacija, o konkrečiai – Schemos Sujungimas.
Kas yra GraphQL Federacija?
GraphQL Federacija yra galinga architektūra, leidžianti sukurti vieną, vieningą GraphQL API iš kelių pagrindinių GraphQL servisų (dažnai atstovaujančių mikroservisus). Ji leidžia programuotojams teikti užklausas duomenims iš skirtingų servisų taip, lyg tai būtų vienas grafas, supaprastinant kliento patirtį ir sumažinant sudėtingos orkestravimo logikos poreikį kliento pusėje.
Yra du pagrindiniai požiūriai į GraphQL Federaciją:
- Schemos Sujungimas (Schema Stitching): Tai apima kelių GraphQL schemų sujungimą į vieną, vieningą schemą sąsajos (gateway) lygmenyje. Tai ankstesnis požiūris, kuris remiasi bibliotekomis, valdančiomis schemų sujungimą ir užklausų delegavimą.
- Apollo Federacija: Tai naujesnis ir tvirtesnis požiūris, kuris naudoja deklaratyvią schemos kalbą ir specializuotą užklausų planuoklį federacijos procesui valdyti. Ji siūlo pažangias funkcijas, tokias kaip tipų plėtiniai, raktų direktyvos ir paskirstytasis sekimas.
Šiame straipsnyje dėmesys skiriamas Schemos Sujungimui, nagrinėjant jo koncepcijas, privalumus, apribojimus ir praktinį įgyvendinimą.
Schemos Sujungimo Supratimas
Schemos sujungimas yra procesas, kurio metu kelios GraphQL schemos sujungiamos į vieną, vientisą schemą. Ši vieninga schema veikia kaip fasadas, slepiantis pagrindinių servisų sudėtingumą nuo kliento. Kai klientas pateikia užklausą sujungtai schemai, sąsaja protingai nukreipia užklausą į atitinkamą pagrindinį servisą (-us), gauna duomenis ir sujungia rezultatus prieš grąžindama juos klientui.
Pagalvokite apie tai taip: turite kelis restoranus (servisus), kurių kiekvienas specializuojasi skirtingose virtuvėse. Schemos sujungimas yra tarsi universalus meniu, kuris apjungia visus patiekalus iš kiekvieno restorano. Kai klientas užsisako iš universalaus meniu, užsakymas protingai nukreipiamas į atitinkamas restoranų virtuves, maistas paruošiamas ir sujungiamas į vieną pristatymą klientui.
Pagrindinės Schemos Sujungimo Koncepcijos
- Nuotolinės Schemos: Tai yra individualios kiekvieno pagrindinio serviso GraphQL schemos. Kiekvienas servisas pateikia savo schemą, kuri apibrėžia jo teikiamus duomenis ir operacijas.
- Sąsaja (Gateway): Sąsaja yra centrinis komponentas, atsakingas už nuotolinių schemų sujungimą ir vieningos schemos pateikimą klientui. Ji gauna kliento užklausas, nukreipia jas į atitinkamus servisus ir sujungia rezultatus.
- Schemų Sujungimas (Schema Merging): Tai yra procesas, kurio metu nuotolinės schemos sujungiamos į vieną schemą. Tai dažnai apima tipų ir laukų pervadinimą, siekiant išvengti konfliktų, ir ryšių tarp tipų apibrėžimą skirtingose schemose.
- Užklausų Delegavimas: Kai klientas pateikia užklausą sujungtai schemai, sąsaja turi deleguoti užklausą atitinkamam pagrindiniam servisui (-ams), kad gautų duomenis. Tai apima kliento užklausos vertimą į užklausą, kurią gali suprasti nuotolinis servisas.
- Rezultatų Agregavimas: Po to, kai sąsaja gauna duomenis iš pagrindinių servisų, ji turi sujungti rezultatus į vieną atsakymą, kurį galima grąžinti klientui. Tai dažnai apima duomenų transformavimą, kad jie atitiktų sujungtos schemos struktūrą.
Schemos Sujungimo Privalumai
Schemos sujungimas siūlo keletą įtikinamų privalumų organizacijoms, taikančioms mikroservisų architektūrą:
- Vieninga API: Suteikia vieną, nuoseklią API klientams, supaprastina duomenų prieigą ir sumažina poreikį klientams tiesiogiai bendrauti su keliais servisais. Tai lemia švaresnę ir intuityvesnę programuotojo patirtį.
- Sumažintas Kliento Sudėtingumas: Klientams tereikia bendrauti su vieninga schema, apsaugant juos nuo pagrindinės mikroservisų architektūros sudėtingumo. Tai supaprastina kliento pusės kūrimą ir sumažina reikalingo kodo kiekį kliento pusėje.
- Padidintas Mastelis: Leidžia nepriklausomai didinti atskirų servisų mastelį pagal jų specifinius poreikius. Tai pagerina bendrą sistemos mastelį ir atsparumą. Pavyzdžiui, vartotojų servisas, patiriantis didelę apkrovą, gali būti didinamas nepaveikiant kitų servisų, tokių kaip produktų katalogas.
- Pagerinta Priežiūra: Skatina moduliškumą ir atsakomybių atskyrimą, todėl lengviau prižiūrėti ir tobulinti atskirus servisus. Vieno serviso pakeitimai mažiau tikėtina, kad paveiks kitus servisus.
- Palaipsnis Pritaikymas: Gali būti įgyvendinamas palaipsniui, leidžiant palaipsniui pereiti nuo monolitinės architektūros prie mikroservisų architektūros. Galite pradėti sujungdami esamas API ir tada palaipsniui skaidyti monolitą į mažesnius servisus.
Schemos Sujungimo Apribojimai
Nors Schemos Sujungimas siūlo daugybę privalumų, svarbu žinoti jo apribojimus:
- Sudėtingumas: Schemos sujungimo įgyvendinimas ir valdymas gali būti sudėtingas, ypač didelėse ir sudėtingose sistemose. Būtinas kruopštus planavimas ir projektavimas.
- Našumo Pridėtinės Išlaidos: Sąsaja sukuria tam tikras našumo pridėtines išlaidas dėl papildomo netiesioginio sluoksnio ir poreikio deleguoti užklausas bei agreguoti rezultatus. Kruopštus optimizavimas yra labai svarbus siekiant sumažinti šias išlaidas.
- Schemų Konfliktai: Konfliktai gali kilti sujungiant schemas iš skirtingų servisų, ypač jei jie naudoja tuos pačius tipų ar laukų pavadinimus. Tam reikalingas kruopštus schemos projektavimas ir galimas tipų bei laukų pervadinimas.
- Ribotos Pažangios Funkcijos: Palyginti su Apollo Federacija, Schemos Sujungimui trūksta kai kurių pažangių funkcijų, tokių kaip tipų plėtiniai ir raktų direktyvos, o tai gali apsunkinti ryšių tarp tipų valdymą skirtingose schemose.
- Įrankių Brandumas: Įrankiai ir ekosistema aplink Schemos Sujungimą nėra tokie brandūs kaip aplink Apollo Federaciją. Dėl to gali būti sunkiau derinti ir šalinti problemas.
Praktinis Schemos Sujungimo Įgyvendinimas
Panagrinėkime supaprastintą pavyzdį, kaip įgyvendinti Schemos Sujungimą naudojant Node.js ir graphql-tools
biblioteką (populiarus pasirinkimas schemų sujungimui). Šis pavyzdys apima du mikroservisus: Vartotojų Servisą ir Produktų Servisą.
1. Apibrėžkite Nuotolines Schemas
Pirmiausia, apibrėžkite GraphQL schemas kiekvienam nuotoliniam servisui.
Vartotojų Servisas (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,
};
Produktų Servisas (product-service.js
):
const { buildSchema } = require('graphql');
const productSchema = buildSchema(`
type Product {
id: ID!
name: String
price: Float
userId: ID! # Svetimasis raktas į Vartotojų Servisą
}
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. Sukurkite Sąsajos Servisą (Gateway)
Dabar sukurkite sąsajos servisą, kuris sujungs abi schemas.
Sąsajos Servisas (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. Paleiskite Servisus
Jums reikės paleisti Vartotojų servisą ir Produktų servisą skirtinguose prievaduose. Pavyzdžiui:
Vartotojų Servisas (prievadas 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'));
Produktų Servisas (prievadas 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. Pateikite Užklausą Sujungtai Schemai
Dabar galite pateikti užklausą sujungtai schemai per sąsają (veikiančią prievade 4000). Galite paleisti tokią užklausą:
query {
product(id: "101") {
id
name
price
user {
id
name
email
}
}
}
Ši užklausa gauna produktą su ID "101" ir taip pat paima susijusį vartotoją iš Vartotojų Serviso, demonstruodama, kaip Schemos Sujungimas leidžia teikti užklausas duomenims iš kelių servisų vienoje užklausoje.
Pažangios Schemos Sujungimo Technikos
Be pagrindinio pavyzdžio, štai keletas pažangių technikų, kurias galima naudoti norint patobulinti Schemos Sujungimo įgyvendinimą:
- Schemos Delegavimas: Tai leidžia deleguoti užklausos dalis skirtingiems servisams, atsižvelgiant į prašomus duomenis. Pavyzdžiui, galite deleguoti `User` tipo sprendimą Vartotojų Servisui, o `Product` tipo sprendimą – Produktų Servisui.
- Schemos Transformavimas: Tai apima nuotolinio serviso schemos modifikavimą prieš ją sujungiant į vieningą schemą. Tai gali būti naudinga pervadinant tipus ir laukus, pridedant naujus laukus arba šalinant esamus.
- Individualūs Rezolveriai (Custom Resolvers): Galite apibrėžti individualius rezolverius sąsajoje, kad tvarkytumėte sudėtingas duomenų transformacijas arba gautumėte duomenis iš kelių servisų ir sujungtumėte juos į vieną rezultatą.
- Konteksto Dalijimasis: Dažnai būtina dalytis konteksto informacija tarp sąsajos ir nuotolinių servisų, pavyzdžiui, autentifikavimo žetonais ar vartotojų ID. Tai galima pasiekti perduodant konteksto informaciją kaip užklausos delegavimo proceso dalį.
- Klaidų Tvarkymas: Įgyvendinkite patikimą klaidų tvarkymą, kad sklandžiai tvarkytumėte klaidas, kurios atsiranda nuotoliniuose servisuose. Tai gali apimti klaidų registravimą, vartotojui draugiškų klaidų pranešimų grąžinimą arba nepavykusių užklausų kartojimą.
Pasirinkimas Tarp Schemos Sujungimo ir Apollo Federacijos
Nors Schemos Sujungimas yra perspektyvus pasirinkimas GraphQL Federacijai, Apollo Federacija tapo populiaresniu pasirinkimu dėl savo pažangių funkcijų ir pagerintos programuotojo patirties. Štai abiejų požiūrių palyginimas:
Savybė | Schemos Sujungimas | Apollo Federacija |
---|---|---|
Schemos Apibrėžimas | Naudoja esamą GraphQL schemos kalbą | Naudoja deklaratyvią schemos kalbą su direktyvomis |
Užklausų Planavimas | Reikalingas rankinis užklausų delegavimas | Automatinis užklausų planavimas Apollo sąsajoje |
Tipų Plėtiniai | Ribotas palaikymas | Integruotas tipų plėtinių palaikymas |
Raktų Direktyvos | Nepalaikoma | Naudoja @key direktyvą esybėms identifikuoti |
Paskirstytasis Sekimas | Reikalingas rankinis įgyvendinimas | Integruotas paskirstytojo sekimo palaikymas |
Įrankiai ir Ekosistema | Mažiau brandūs įrankiai | Brandesni įrankiai ir didelė bendruomenė |
Sudėtingumas | Gali būti sudėtinga valdyti didelėse sistemose | Sukurta didelėms ir sudėtingoms sistemoms |
Kada Rinktis Schemos Sujungimą:
- Turite esamus GraphQL servisus ir norite juos greitai sujungti.
- Jums reikia paprasto federacijos sprendimo ir nereikia pažangių funkcijų.
- Turite ribotus resursus ir norite išvengti pridėtinių išlaidų, susijusių su Apollo Federacijos nustatymu.
Kada Rinktis Apollo Federaciją:
- Kuriate didelę ir sudėtingą sistemą su keliomis komandomis ir servisais.
- Jums reikia pažangių funkcijų, tokių kaip tipų plėtiniai, raktų direktyvos ir paskirstytasis sekimas.
- Norite tvirtesnio ir labiau mastelį didinančio federacijos sprendimo.
- Teikiate pirmenybę deklaratyvesniam ir automatizuotam požiūriui į federaciją.
Realūs Pavyzdžiai ir Panaudojimo Atvejai
Štai keletas realaus pasaulio pavyzdžių, kaip gali būti naudojama GraphQL Federacija, įskaitant Schemos Sujungimą:
- El. prekybos Platforma: El. prekybos platforma gali naudoti GraphQL Federaciją, kad sujungtų duomenis iš kelių servisų, tokių kaip produktų katalogo servisas, vartotojų servisas, užsakymų servisas ir mokėjimų servisas. Tai leidžia klientams lengvai gauti visą informaciją, reikalingą produktų detalėms, vartotojų profiliams, užsakymų istorijai ir mokėjimų informacijai rodyti.
- Socialinių Tinklų Platforma: Socialinių tinklų platforma galėtų naudoti GraphQL Federaciją, kad sujungtų duomenis iš servisų, valdančių vartotojų profilius, įrašus, komentarus ir „patinka“ paspaudimus. Tai leidžia klientams efektyviai gauti visą informaciją, reikalingą vartotojo profiliui, jo įrašams bei su tais įrašais susijusiems komentarams ir „patinka“ paspaudimams rodyti.
- Finansinių Paslaugų Aplikacija: Finansinių paslaugų aplikacija gali naudoti GraphQL Federaciją, kad sujungtų duomenis iš servisų, valdančių sąskaitas, transakcijas ir investicijas. Tai leidžia klientams lengvai gauti visą informaciją, reikalingą sąskaitų likučiams, transakcijų istorijai ir investiciniams portfeliams rodyti.
- Turinio Valdymo Sistema (TVS): TVS gali panaudoti GraphQL Federaciją, kad integruotų duomenis iš įvairių šaltinių, tokių kaip straipsniai, vaizdai, vaizdo įrašai ir vartotojų sukurtas turinys. Tai leidžia sukurti vieningą API, kad būtų galima gauti visą turinį, susijusį su konkrečia tema ar autoriumi.
- Sveikatos Priežiūros Aplikacija: Integruokite pacientų duomenis iš skirtingų sistemų, tokių kaip elektroniniai sveikatos įrašai (EHR), laboratorinių tyrimų rezultatai ir vizitų planavimas. Tai suteikia gydytojams vieną prieigos tašką prie išsamios paciento informacijos.
Geriausios Schemos Sujungimo Praktikos
Norėdami užtikrinti sėkmingą Schemos Sujungimo įgyvendinimą, laikykitės šių geriausių praktikų:
- Kruopščiai Suplanuokite Savo Schemą: Prieš pradėdami jungti schemas, kruopščiai suplanuokite vieningos schemos struktūrą. Tai apima ryšių tarp tipų apibrėžimą skirtingose schemose, tipų ir laukų pervadinimą siekiant išvengti konfliktų ir bendrų duomenų prieigos modelių apsvarstymą.
- Naudokite Nuoseklias Pavadinimų Taisykles: Priimkite nuoseklias pavadinimų taisykles tipams, laukams ir operacijoms visuose servisuose. Tai padės išvengti konfliktų ir palengvins vieningos schemos supratimą.
- Dokumentuokite Savo Schemą: Kruopščiai dokumentuokite vieningą schemą, įskaitant tipų, laukų ir operacijų aprašymus. Tai palengvins programuotojams suprasti ir naudoti schemą.
- Stebėkite Našumą: Stebėkite sąsajos ir nuotolinių servisų našumą, kad nustatytumėte ir pašalintumėte bet kokius našumo trukdžius. Naudokite įrankius, tokius kaip paskirstytasis sekimas, kad stebėtumėte užklausas keliuose servisuose.
- Įgyvendinkite Saugumą: Įgyvendinkite tinkamas saugumo priemones, kad apsaugotumėte sąsają ir nuotolinius servisus nuo neautorizuotos prieigos. Tai gali apimti autentifikavimo ir autorizavimo mechanizmų naudojimą, taip pat įvesties patvirtinimą ir išvesties kodavimą.
- Versijuokite Savo Schemą: Tobulindami schemas, tinkamai jas versijuokite, kad klientai galėtų toliau naudoti senesnes schemos versijas be sutrikimų. Tai padės išvengti esminių pakeitimų ir užtikrins atgalinį suderinamumą.
- Automatizuokite Diegimą: Automatizuokite sąsajos ir nuotolinių servisų diegimą, kad pakeitimai galėtų būti įdiegti greitai ir patikimai. Tai padės sumažinti klaidų riziką ir pagerins bendrą sistemos lankstumą.
Išvada
GraphQL Federacija su Schemos Sujungimu siūlo galingą požiūrį į vieningų API kūrimą iš kelių servisų mikroservisų architektūroje. Suprasdami jos pagrindines koncepcijas, privalumus, apribojimus ir įgyvendinimo technikas, galite panaudoti Schemos Sujungimą, kad supaprastintumėte duomenų prieigą, pagerintumėte mastelį ir padidintumėte priežiūros patogumą. Nors Apollo Federacija tapo pažangesniu sprendimu, Schemos Sujungimas išlieka perspektyvus pasirinkimas paprastesniems scenarijams arba integruojant esamus GraphQL servisus. Atidžiai apsvarstykite savo specifinius poreikius ir reikalavimus, kad pasirinktumėte geriausią požiūrį savo organizacijai.