Hyödynnä GraphQL-federaation teho skeemojen yhdistämisen avulla. Opi rakentamaan yhtenäinen GraphQL API useista palveluista, parantaen skaalautuvuutta ja ylläpidettävyyttä.
GraphQL-federaatio: Skeemojen yhdistäminen (Schema Stitching) - Kattava opas
Nykyaikaisen sovelluskehityksen jatkuvasti muuttuvassa maisemassa skaalautuvien ja ylläpidettävien arkkitehtuurien tarve on tullut ensiarvoisen tärkeäksi. Mikropalvelut, luontaisella modulaarisuudellaan ja itsenäisellä käyttöönotettavuudellaan, ovat nousseet suosituksi ratkaisuksi. Useiden mikropalveluiden hallinta voi kuitenkin tuoda mukanaan monimutkaisuutta, erityisesti kun tarkoituksena on tarjota yhtenäinen API asiakassovelluksille. Tässä kohtaa GraphQL-federaatio, ja erityisesti skeemojen yhdistäminen (Schema Stitching), astuu kuvaan.
Mitä on GraphQL-federaatio?
GraphQL-federaatio on tehokas arkkitehtuuri, joka mahdollistaa yhtenäisen GraphQL API:n rakentamisen useista taustalla olevista GraphQL-palveluista (jotka usein edustavat mikropalveluita). Se antaa kehittäjille mahdollisuuden hakea dataa eri palveluista ikään kuin ne olisivat yksi ainoa graafi, mikä yksinkertaistaa asiakaskokemusta ja vähentää tarvetta monimutkaiselle orkestrointilogiikalle asiakaspäässä.
GraphQL-federaatioon on kaksi pääasiallista lähestymistapaa:
- Skeemojen yhdistäminen (Schema Stitching): Tämä tarkoittaa useiden GraphQL-skeemojen yhdistämistä yhdeksi, yhtenäiseksi skeemaksi yhdyskäytäväkerroksella (gateway). Se on vanhempi lähestymistapa ja perustuu kirjastoihin, jotka hallitsevat skeemojen yhdistämistä ja kyselyiden delegointia.
- Apollo Federation: Tämä on uudempi ja vankempi lähestymistapa, joka käyttää deklaratiivista skeemakieltä ja erillistä kyselysuunnittelijaa federaatioprosessin hallintaan. Se tarjoaa edistyneitä ominaisuuksia, kuten tyyppien laajennuksia, avaindirektiivejä ja hajautettua jäljitystä.
Tämä artikkeli keskittyy skeemojen yhdistämiseen, tutkien sen käsitteitä, etuja, rajoituksia ja käytännön toteutusta.
Skeemojen yhdistämisen ymmärtäminen
Skeemojen yhdistäminen on prosessi, jossa useita GraphQL-skeemoja yhdistetään yhdeksi, yhtenäiseksi skeemaksi. Tämä yhtenäinen skeema toimii julkisivuna, joka piilottaa taustalla olevien palveluiden monimutkaisuuden asiakkaalta. Kun asiakas tekee pyynnön yhdistettyyn skeemaan, yhdyskäytävä reitittää pyynnön älykkäästi asianmukaiseen taustapalveluun (tai palveluihin), noutaa datan ja yhdistää tulokset ennen niiden palauttamista asiakkaalle.
Ajattele sitä näin: Sinulla on useita ravintoloita (palveluita), jotka ovat erikoistuneet eri keittiöihin. Skeemojen yhdistäminen on kuin yleismenu, joka yhdistää kaikki ruokalajit jokaisesta ravintolasta. Kun asiakas (client) tilaa yleismenusta, tilaus reititetään älykkäästi oikeisiin ravintolakeittiöihin, ruoka valmistetaan ja yhdistetään sitten yhdeksi toimitukseksi asiakkaalle.
Skeemojen yhdistämisen avainkäsitteet
- Etäskeemat (Remote Schemas): Nämä ovat yksittäisten taustapalveluiden GraphQL-skeemoja. Jokainen palvelu paljastaa oman skeemansa, joka määrittelee sen tarjoaman datan ja operaatiot.
- Yhdyskäytävä (Gateway): Yhdyskäytävä on keskeinen komponentti, joka vastaa etäskeemojen yhteen liittämisestä ja yhtenäisen skeeman tarjoamisesta asiakkaalle. Se vastaanottaa asiakaspyyntöjä, reitittää ne sopiviin palveluihin ja yhdistää tulokset.
- Skeemojen yhdistäminen (Schema Merging): Tämä on prosessi, jossa etäskeemat yhdistetään yhdeksi skeemaksi. Tämä edellyttää usein tyyppien ja kenttien nimeämistä uudelleen konfliktien välttämiseksi sekä suhteiden määrittelyä eri skeemojen tyyppien välillä.
- Kyselyjen delegointi (Query Delegation): Kun asiakas tekee pyynnön yhdistettyyn skeemaan, yhdyskäytävän on delegoitava pyyntö asianmukaiseen taustapalveluun (tai palveluihin) datan noutamiseksi. Tämä tarkoittaa asiakkaan kyselyn kääntämistä kyselyksi, jonka etäpalvelu ymmärtää.
- Tulosten yhdistäminen (Result Aggregation): Kun yhdyskäytävä on noutanut datan taustapalveluista, sen on yhdistettävä tulokset yhdeksi vastaukseksi, joka voidaan palauttaa asiakkaalle. Tämä tarkoittaa usein datan muuntamista vastaamaan yhdistetyn skeeman rakennetta.
Skeemojen yhdistämisen edut
Skeemojen yhdistäminen tarjoaa useita merkittäviä etuja organisaatioille, jotka käyttävät mikropalveluarkkitehtuuria:
- Yhtenäinen API: Tarjoaa yhden, johdonmukaisen API:n asiakkaille, mikä yksinkertaistaa datan käyttöä ja vähentää asiakkaiden tarvetta olla suoraan vuorovaikutuksessa useiden palveluiden kanssa. Tämä johtaa puhtaampaan ja intuitiivisempaan kehittäjäkokemukseen.
- Asiakaspään monimutkaisuuden vähentäminen: Asiakkaiden tarvitsee olla vuorovaikutuksessa vain yhtenäisen skeeman kanssa, mikä suojaa heitä taustalla olevan mikropalveluarkkitehtuurin monimutkaisuudelta. Tämä yksinkertaistaa asiakaspään kehitystä ja vähentää asiakassovelluksessa vaadittavan koodin määrää.
- Parempi skaalautuvuus: Mahdollistaa yksittäisten palveluiden skaalaamisen itsenäisesti niiden erityistarpeiden mukaan. Tämä parantaa järjestelmän yleistä skaalautuvuutta ja kestävyyttä. Esimerkiksi suuren kuormituksen alaisena oleva käyttäjäpalvelu voidaan skaalata vaikuttamatta muihin palveluihin, kuten tuotekatalogiin.
- Parempi ylläpidettävyys: Edistää modulaarisuutta ja vastuualueiden erottamista, mikä helpottaa yksittäisten palveluiden ylläpitoa ja kehittämistä. Muutokset yhteen palveluun vaikuttavat vähemmän todennäköisesti muihin palveluihin.
- Asteittainen käyttöönotto: Voidaan toteuttaa vaiheittain, mikä mahdollistaa asteittaisen siirtymisen monoliittisesta arkkitehtuurista mikropalveluarkkitehtuuriin. Voit aloittaa yhdistämällä olemassa olevia API:ita ja sitten vähitellen hajottaa monoliitin pienemmiksi palveluiksi.
Skeemojen yhdistämisen rajoitukset
Vaikka skeemojen yhdistäminen tarjoaa lukuisia etuja, on tärkeää olla tietoinen sen rajoituksista:
- Monimutkaisuus: Skeemojen yhdistämisen toteuttaminen ja hallinta voi olla monimutkaista, erityisesti suurissa ja monimutkaisissa järjestelmissä. Huolellinen suunnittelu on välttämätöntä.
- Suorituskyky-ylikuorma: Yhdyskäytävä aiheuttaa jonkin verran suorituskyky-ylikuormaa ylimääräisen kerroksen ja kyselyiden delegointitarpeen sekä tulosten yhdistämisen vuoksi. Huolellinen optimointi on ratkaisevan tärkeää tämän ylikuorman minimoimiseksi.
- Skeemakonfliktit: Konflikteja voi syntyä, kun eri palveluiden skeemoja yhdistetään, varsinkin jos ne käyttävät samoja tyyppien tai kenttien nimiä. Tämä vaatii huolellista skeemasuunnittelua ja mahdollisesti tyyppien ja kenttien uudelleennimeämistä.
- Rajoitetut edistyneet ominaisuudet: Verrattuna Apollo Federationiin, Schema Stitchingistä puuttuu joitakin edistyneitä ominaisuuksia, kuten tyyppien laajennukset ja avaindirektiivit, mikä voi tehdä suhteiden hallinnasta eri skeemojen tyyppien välillä haastavampaa.
- Työkalujen kypsyys: Schema Stitchingin ympärillä olevat työkalut ja ekosysteemi eivät ole yhtä kypsiä kuin Apollo Federationin. Tämä voi tehdä virheiden etsinnästä ja ongelmien ratkaisemisesta haastavampaa.
Skeemojen yhdistämisen käytännön toteutus
Käydään läpi yksinkertaistettu esimerkki siitä, miten Schema Stitching toteutetaan Node.js:llä ja graphql-tools
-kirjastolla (suosittu valinta skeemojen yhdistämiseen). Tämä esimerkki sisältää kaksi mikropalvelua: Käyttäjäpalvelun ja Tuotepalvelun.
1. Määritä etäskeemat
Määritä ensin GraphQL-skeemat kullekin etäpalvelulle.
Käyttäjäpalvelu (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,
};
Tuotepalvelu (product-service.js
):
const { buildSchema } = require('graphql');
const productSchema = buildSchema(`
type Product {
id: ID!
name: String
price: Float
userId: ID! # Foreign key to User Service
}
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. Luo yhdyskäytäväpalvelu
Luo nyt yhdyskäytäväpalvelu, joka yhdistää kaksi skeemaa.
Yhdyskäytäväpalvelu (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. Suorita palvelut
Sinun täytyy suorittaa käyttäjäpalvelu ja tuotepalvelu eri porteissa. Esimerkiksi:
Käyttäjäpalvelu (portti 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'));
Tuotepalvelu (portti 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. Tee kysely yhdistettyyn skeemaan
Nyt voit tehdä kyselyn yhdistettyyn skeemaan yhdyskäytävän kautta (joka toimii portissa 4000). Voit suorittaa seuraavanlaisen kyselyn:
query {
product(id: "101") {
id
name
price
user {
id
name
email
}
}
}
Tämä kysely noutaa tuotteen, jonka ID on "101", ja hakee myös siihen liittyvän käyttäjän käyttäjäpalvelusta, osoittaen, miten Schema Stitching mahdollistaa datan hakemisen useista palveluista yhdellä pyynnöllä.
Edistyneet Schema Stitching -tekniikat
Perusesimerkin lisäksi tässä on joitakin edistyneitä tekniikoita, joita voidaan käyttää Schema Stitching -toteutuksen parantamiseen:
- Skeeman delegointi: Tämä mahdollistaa kyselyn osien delegoinnin eri palveluille pyydettävän datan perusteella. Esimerkiksi voit delegoida `User`-tyypin ratkaisun käyttäjäpalveluun ja `Product`-tyypin ratkaisun tuotepalveluun.
- Skeeman muuntaminen: Tähän sisältyy etäpalvelun skeeman muokkaaminen ennen sen yhdistämistä yhtenäiseen skeemaan. Tämä voi olla hyödyllistä tyyppien ja kenttien uudelleennimeämiseen, uusien kenttien lisäämiseen tai olemassa olevien kenttien poistamiseen.
- Mukautetut resolverit: Voit määritellä yhdyskäytävään mukautettuja resolvereita käsittelemään monimutkaisia datamuunnoksia tai noutamaan dataa useista palveluista ja yhdistämään sen yhdeksi tulokseksi.
- Kontekstin jakaminen: On usein tarpeen jakaa kontekstitietoa, kuten todennustunnisteita tai käyttäjätunnuksia, yhdyskäytävän ja etäpalveluiden välillä. Tämä voidaan saavuttaa välittämällä kontekstitietoa osana kyselyn delegointiprosessia.
- Virheidenkäsittely: Toteuta vankka virheidenkäsittely käsitelläksesi etäpalveluissa ilmenevät virheet sulavasti. Tämä voi sisältää virheiden kirjaamista, käyttäjäystävällisten virheilmoitusten palauttamista tai epäonnistuneiden pyyntöjen uudelleen yrittämistä.
Schema Stitchingin ja Apollo Federationin välillä valitseminen
Vaikka Schema Stitching on toimiva vaihtoehto GraphQL-federaatiolle, Apollo Federationista on tullut suositumpi valinta sen edistyneiden ominaisuuksien ja parantuneen kehittäjäkokemuksen vuoksi. Tässä on vertailu näistä kahdesta lähestymistavasta:
Ominaisuus | Schema Stitching | Apollo Federation |
---|---|---|
Skeeman määrittely | Käyttää olemassa olevaa GraphQL-skeemakieltä | Käyttää deklaratiivista skeemakieltä direktiiveillä |
Kyselyn suunnittelu | Vaatii manuaalista kyselyn delegointia | Automaattinen kyselyn suunnittelu Apollo Gatewayn toimesta |
Tyyppien laajennukset | Rajoitettu tuki | Sisäänrakennettu tuki tyyppien laajennuksille |
Avaindirektiivit | Ei tuettu | Käyttää @key -direktiiviä entiteettien tunnistamiseen |
Hajautettu jäljitys | Vaatii manuaalisen toteutuksen | Sisäänrakennettu tuki hajautetulle jäljitykselle |
Työkalut ja ekosysteemi | Vähemmän kypsät työkalut | Kypsemmät työkalut ja suuri yhteisö |
Monimutkaisuus | Voi olla monimutkaista hallita suurissa järjestelmissä | Suunniteltu suuriin ja monimutkaisiin järjestelmiin |
Milloin valita Schema Stitching:
- Sinulla on olemassa olevia GraphQL-palveluita ja haluat nopeasti yhdistää ne.
- Tarvitset yksinkertaisen federaatioratkaisun etkä vaadi edistyneitä ominaisuuksia.
- Sinulla on rajalliset resurssit ja haluat välttää Apollo Federationin pystyttämisen aiheuttaman lisätyön.
Milloin valita Apollo Federation:
- Olet rakentamassa suurta ja monimutkaista järjestelmää, jossa on useita tiimejä ja palveluita.
- Tarvitset edistyneitä ominaisuuksia, kuten tyyppien laajennuksia, avaindirektiivejä ja hajautettua jäljitystä.
- Haluat vankemman ja skaalautuvamman federaatioratkaisun.
- Suosit deklaratiivisempaa ja automatisoidumpaa lähestymistapaa federaatioon.
Tosielämän esimerkkejä ja käyttötapauksia
Tässä on joitakin tosielämän esimerkkejä siitä, miten GraphQL-federaatiota, mukaan lukien Schema Stitching, voidaan käyttää:
- Verkkokauppa-alusta: Verkkokauppa-alusta voi käyttää GraphQL-federaatiota yhdistääkseen dataa useista palveluista, kuten tuotekatalogipalvelusta, käyttäjäpalvelusta, tilauspalvelusta ja maksupalvelusta. Tämä antaa asiakkaille mahdollisuuden hakea helposti kaikki tiedot, joita he tarvitsevat tuotetietojen, käyttäjäprofiilien, tilaushistorian ja maksutietojen näyttämiseen.
- Sosiaalisen median alusta: Sosiaalisen median alusta voisi käyttää GraphQL-federaatiota yhdistääkseen dataa palveluista, jotka hallinnoivat käyttäjäprofiileja, julkaisuja, kommentteja ja tykkäyksiä. Tämä mahdollistaa asiakkaille tehokkaasti kaiken tarvittavan tiedon noutamisen käyttäjän profiilin, hänen julkaisujensa sekä niihin liittyvien kommenttien ja tykkäysten näyttämiseksi.
- Rahoituspalvelusovellus: Rahoituspalvelusovellus voi käyttää GraphQL-federaatiota yhdistääkseen dataa palveluista, jotka hallinnoivat tilejä, tapahtumia ja sijoituksia. Tämä antaa asiakkaille mahdollisuuden hakea helposti kaikki tiedot, joita he tarvitsevat tilisaldon, tapahtumahistorian ja sijoitussalkkujen näyttämiseen.
- Sisällönhallintajärjestelmä (CMS): CMS voi hyödyntää GraphQL-federaatiota integroidakseen dataa eri lähteistä, kuten artikkeleista, kuvista, videoista ja käyttäjien luomasta sisällöstä. Tämä mahdollistaa yhtenäisen API:n, jolla voidaan hakea kaikki tiettyyn aiheeseen tai kirjoittajaan liittyvä sisältö.
- Terveydenhuollon sovellus: Integroi potilastietoja eri järjestelmistä, kuten sähköisistä potilaskertomuksista (EHR), laboratoriotuloksista ja ajanvarauksista. Tämä tarjoaa lääkäreille yhden pisteen, josta pääsee käsiksi kattaviin potilastietoihin.
Parhaat käytännöt Schema Stitchingiin
Varmistaaksesi onnistuneen Schema Stitching -toteutuksen, noudata näitä parhaita käytäntöjä:
- Suunnittele skeemasi huolellisesti: Ennen kuin aloitat skeemojen yhdistämisen, suunnittele yhtenäisen skeeman rakenne huolellisesti. Tämä sisältää suhteiden määrittelyn eri skeemojen tyyppien välillä, tyyppien ja kenttien uudelleennimeämisen konfliktien välttämiseksi sekä yleisten datankäyttömallien huomioon ottamisen.
- Käytä johdonmukaisia nimeämiskäytäntöjä: Ota käyttöön johdonmukaiset nimeämiskäytännöt tyypeille, kentille ja operaatioille kaikissa palveluissa. Tämä auttaa välttämään konflikteja ja helpottaa yhtenäisen skeeman ymmärtämistä.
- Dokumentoi skeemasi: Dokumentoi yhtenäinen skeema perusteellisesti, mukaan lukien tyyppien, kenttien ja operaatioiden kuvaukset. Tämä helpottaa kehittäjien skeeman ymmärtämistä ja käyttöä.
- Seuraa suorituskykyä: Seuraa yhdyskäytävän ja etäpalveluiden suorituskykyä tunnistaaksesi ja korjataksesi mahdolliset suorituskyvyn pullonkaulat. Käytä työkaluja, kuten hajautettua jäljitystä, seurataksesi pyyntöjä useiden palveluiden välillä.
- Toteuta tietoturva: Toteuta asianmukaiset turvatoimet suojataksesi yhdyskäytävää ja etäpalveluita luvattomalta käytöltä. Tämä voi sisältää todennus- ja valtuutusmekanismien käyttöä sekä syötteen validointia ja tulosteen koodausta.
- Versioi skeemasi: Kun kehität skeemojasi, versioi ne asianmukaisesti varmistaaksesi, että asiakkaat voivat jatkaa skeeman vanhempien versioiden käyttöä ilman, että mikään hajoaa. Tämä auttaa välttämään rikkovia muutoksia ja varmistamaan taaksepäin yhteensopivuuden.
- Automatisoi käyttöönotto: Automatisoi yhdyskäytävän ja etäpalveluiden käyttöönotto varmistaaksesi, että muutokset voidaan ottaa käyttöön nopeasti ja luotettavasti. Tämä auttaa vähentämään virheiden riskiä ja parantamaan järjestelmän yleistä ketteryyttä.
Yhteenveto
GraphQL-federaatio ja Schema Stitching tarjoavat tehokkaan lähestymistavan yhtenäisten API:iden rakentamiseen useista palveluista mikropalveluarkkitehtuurissa. Ymmärtämällä sen ydinajatukset, edut, rajoitukset ja toteutustekniikat, voit hyödyntää Schema Stitchingiä yksinkertaistaaksesi datan käyttöä, parantaaksesi skaalautuvuutta ja tehostaaksesi ylläpidettävyyttä. Vaikka Apollo Federation on noussut edistyneemmäksi ratkaisuksi, Schema Stitching on edelleen varteenotettava vaihtoehto yksinkertaisemmissa tapauksissa tai integroidessa olemassa olevia GraphQL-palveluita. Harkitse huolellisesti erityistarpeitasi ja vaatimuksiasi valitaksesi parhaan lähestymistavan organisaatiollesi.