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:
- Združevanje shem (Schema Stitching): To vključuje združevanje več shem GraphQL v eno samo, enotno shemo na ravni prehoda (gateway). To je starejši pristop, ki se za upravljanje združevanja shem in delegiranja poizvedb opira na knjižnice.
- Federacija Apollo: To je novejši in robustnejši pristop, ki za upravljanje procesa federacije uporablja deklarativni jezik shem in namenski načrtovalec poizvedb. Ponuja napredne funkcije, kot so razširitve tipov, ključne direktive in porazdeljeno sledenje.
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
- Oddaljene sheme: To so posamezne sheme GraphQL vsake osnovne storitve. Vsaka storitev izpostavi svojo shemo, ki definira podatke in operacije, ki jih ponuja.
- Prehod (Gateway): Prehod je osrednja komponenta, odgovorna za združevanje oddaljenih shem in izpostavitev enotne sheme odjemalcu. Prejema zahteve odjemalcev, jih usmerja v ustrezne storitve in združuje rezultate.
- Združevanje shem: To je postopek združevanja oddaljenih shem v eno samo shemo. To pogosto vključuje preimenovanje tipov in polj, da se izognemo konfliktom, ter definiranje razmerij med tipi v različnih shemah.
- Delegiranje poizvedb: Ko odjemalec pošlje zahtevo na združeno shemo, mora prehod delegirati zahtevo ustrezni osnovni storitvi (ali storitvam), da pridobi podatke. To vključuje prevajanje poizvedbe odjemalca v poizvedbo, ki jo lahko razume oddaljena storitev.
- Združevanje rezultatov: Ko prehod pridobi podatke iz osnovnih storitev, mora združiti rezultate v en sam odgovor, ki ga lahko vrne odjemalcu. To pogosto vključuje transformacijo podatkov, da se ujemajo s strukturo združene sheme.
Prednosti združevanja shem
Združevanje shem ponuja več prepričljivih prednosti za organizacije, ki uporabljajo arhitekturo mikrostoritev:
- Enoten API: Zagotavlja en sam, dosleden API za odjemalce, kar poenostavlja dostop do podatkov in zmanjšuje potrebo, da bi odjemalci neposredno komunicirali z več storitvami. To vodi do čistejše in bolj intuitivne izkušnje za razvijalce.
- Zmanjšana kompleksnost na strani odjemalca: Odjemalci morajo komunicirati le z enotno shemo, kar jih ščiti pred kompleksnostjo osnovne arhitekture mikrostoritev. To poenostavlja razvoj na strani odjemalca in zmanjšuje količino kode, potrebne na odjemalcu.
- Povečana razširljivost: Omogoča neodvisno prilagajanje posameznih storitev glede na njihove specifične potrebe. To izboljša splošno razširljivost in odpornost sistema. Na primer, storitev za uporabnike, ki doživlja visoko obremenitev, se lahko prilagodi brez vpliva na druge storitve, kot je katalog izdelkov.
- Izboljšana vzdržljivost: Spodbuja modularnost in ločevanje odgovornosti, kar olajša vzdrževanje in razvoj posameznih storitev. Manj verjetno je, da bodo spremembe v eni storitvi vplivale na druge storitve.
- Postopno uvajanje: Lahko se implementira postopoma, kar vam omogoča postopno migracijo z monolitne arhitekture na arhitekturo mikrostoritev. Začnete lahko z združevanjem obstoječih API-jev in nato postopoma razgradite monolit na manjše storitve.
Omejitve združevanja shem
Čeprav združevanje shem ponuja številne prednosti, se je pomembno zavedati njegovih omejitev:
- Kompleksnost: Implementacija in upravljanje združevanja shem sta lahko zapletena, zlasti v velikih in kompleksnih sistemih. Nujno je skrbno načrtovanje in oblikovanje.
- Dodatna obremenitev zmogljivosti: Prehod uvaja nekaj dodatne obremenitve zmogljivosti zaradi dodatne plasti posredovanja ter potrebe po delegiranju poizvedb in združevanju rezultatov. Za zmanjšanje te obremenitve je ključnega pomena skrbna optimizacija.
- Konflikti shem: Pri združevanju shem iz različnih storitev lahko pride do konfliktov, zlasti če uporabljajo ista imena tipov ali polj. To zahteva skrbno oblikovanje shem in potencialno preimenovanje tipov in polj.
- Omejene napredne funkcije: V primerjavi s federacijo Apollo združevanju shem primanjkuje nekaterih naprednih funkcij, kot so razširitve tipov in ključne direktive, kar lahko oteži upravljanje razmerij med tipi v različnih shemah.
- Zrelost orodij: Orodja in ekosistem okoli združevanja shem niso tako zreli kot tisti okoli federacije Apollo. To lahko oteži odpravljanje napak in reševanje težav.
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:
- Delegiranje sheme: To vam omogoča delegiranje delov poizvedbe različnim storitvam glede na zahtevane podatke. Na primer, lahko delegirate razreševanje tipa `User` na storitev za uporabnike in razreševanje tipa `Product` na storitev za izdelke.
- Transformacija sheme: To vključuje spreminjanje sheme oddaljene storitve, preden se združi v enotno shemo. To je lahko uporabno za preimenovanje tipov in polj, dodajanje novih polj ali odstranjevanje obstoječih polj.
- Razreševalniki po meri: V prehodu lahko definirate razreševalnike po meri za obravnavo kompleksnih transformacij podatkov ali za pridobivanje podatkov iz več storitev in njihovo združevanje v en sam rezultat.
- Deljenje konteksta: Pogosto je treba deliti informacije o kontekstu med prehodom in oddaljenimi storitvami, kot so avtentikacijski žetoni ali ID-ji uporabnikov. To je mogoče doseči s posredovanjem informacij o kontekstu kot del procesa delegiranja poizvedb.
- Obravnavanje napak: Implementirajte robustno obravnavanje napak za elegantno obravnavo napak, ki se pojavijo v oddaljenih storitvah. To lahko vključuje beleženje napak, vračanje uporabniku prijaznih sporočil o napakah ali ponavljanje neuspelih zahtev.
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:
- Imate obstoječe storitve GraphQL in jih želite hitro združiti.
- Potrebujete preprosto rešitev za federacijo in ne potrebujete naprednih funkcij.
- Imate omejene vire in se želite izogniti dodatnim stroškom postavitve federacije Apollo.
Kdaj izbrati federacijo Apollo:
- Gradite velik in kompleksen sistem z več ekipami in storitvami.
- Potrebujete napredne funkcije, kot so razširitve tipov, ključne direktive in porazdeljeno sledenje.
- Želite bolj robustno in razširljivo rešitev za federacijo.
- Raje imate bolj deklarativen in avtomatiziran pristop k federaciji.
Primeri iz prakse in primeri uporabe
Tukaj je nekaj primerov iz prakse, kako se lahko uporablja federacija GraphQL, vključno z združevanjem shem:
- Platforma za e-trgovino: Platforma za e-trgovino bi lahko uporabila federacijo GraphQL za združevanje podatkov iz več storitev, kot so storitev za katalog izdelkov, storitev za uporabnike, storitev za naročila in plačilna storitev. To odjemalcem omogoča enostavno pridobivanje vseh informacij, ki jih potrebujejo za prikaz podrobnosti o izdelkih, profilov uporabnikov, zgodovine naročil in informacij o plačilih.
- Platforma za družbena omrežja: Platforma za družbena omrežja bi lahko uporabila federacijo GraphQL za združevanje podatkov iz storitev, ki upravljajo profile uporabnikov, objave, komentarje in všečke. To odjemalcem omogoča učinkovito pridobivanje vseh informacij, potrebnih za prikaz uporabnikovega profila, njegovih objav ter komentarjev in všečkov, povezanih s temi objavami.
- Aplikacija za finančne storitve: Aplikacija za finančne storitve bi lahko uporabila federacijo GraphQL za združevanje podatkov iz storitev, ki upravljajo račune, transakcije in naložbe. To odjemalcem omogoča enostavno pridobivanje vseh informacij, ki jih potrebujejo za prikaz stanj na računih, zgodovine transakcij in naložbenih portfeljev.
- Sistem za upravljanje vsebin (CMS): CMS lahko izkoristi federacijo GraphQL za integracijo podatkov iz različnih virov, kot so članki, slike, videoposnetki in vsebina, ki jo ustvarijo uporabniki. To omogoča enoten API za pridobivanje vse vsebine, povezane z določeno temo ali avtorjem.
- Aplikacija v zdravstvu: Integracija podatkov o pacientih iz različnih sistemov, kot so elektronski zdravstveni kartoni (EHR), laboratorijski rezultati in urniki terminov. To zdravnikom ponuja eno samo točko dostopa do celovitih informacij o pacientih.
Najboljše prakse za združevanje shem
Da bi zagotovili uspešno implementacijo združevanja shem, upoštevajte te najboljše prakse:
- Skrbno načrtujte svojo shemo: Preden začnete združevati sheme, skrbno načrtujte strukturo enotne sheme. To vključuje definiranje razmerij med tipi v različnih shemah, preimenovanje tipov in polj, da se izognete konfliktom, ter upoštevanje splošnih vzorcev dostopa do podatkov.
- Uporabljajte dosledne konvencije poimenovanja: Sprejmite dosledne konvencije poimenovanja za tipe, polja in operacije v vseh storitvah. To bo pomagalo preprečiti konflikte in olajšalo razumevanje enotne sheme.
- Dokumentirajte svojo shemo: Temeljito dokumentirajte enotno shemo, vključno z opisi tipov, polj in operacij. To bo razvijalcem olajšalo razumevanje in uporabo sheme.
- Spremljajte zmogljivost: Spremljajte delovanje prehoda in oddaljenih storitev, da prepoznate in odpravite morebitna ozka grla v zmogljivosti. Za sledenje zahtevam v več storitvah uporabite orodja, kot je porazdeljeno sledenje.
- Implementirajte varnost: Implementirajte ustrezne varnostne ukrepe za zaščito prehoda in oddaljenih storitev pred nepooblaščenim dostopom. To lahko vključuje uporabo mehanizmov za avtentikacijo in avtorizacijo ter preverjanje veljavnosti vnosov in kodiranje izhodov.
- Upravljajte z različicami svoje sheme: Med razvojem svojih shem jih ustrezno različicirajte, da zagotovite, da lahko odjemalci še naprej uporabljajo starejše različice sheme brez napak. To bo pomagalo preprečiti moteče spremembe in zagotoviti združljivost za nazaj.
- Avtomatizirajte uvajanje: Avtomatizirajte uvajanje prehoda in oddaljenih storitev, da zagotovite hitro in zanesljivo uvajanje sprememb. To bo pomagalo zmanjšati tveganje za napake in izboljšati splošno agilnost sistema.
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.