Ontgrendel de kracht van GraphQL Federatie met Schema Stitching. Leer hoe u een uniforme GraphQL API bouwt vanuit meerdere services, voor een betere schaalbaarheid en onderhoudbaarheid.
GraphQL Federatie: Schema Stitching - Een Uitgebreide Gids
In het steeds evoluerende landschap van moderne applicatieontwikkeling is de behoefte aan schaalbare en onderhoudbare architecturen van het grootste belang geworden. Microservices, met hun inherente modulariteit en onafhankelijke inzetbaarheid, zijn een populaire oplossing geworden. Het beheren van talrijke microservices kan echter complexiteiten met zich meebrengen, vooral als het gaat om het aanbieden van een uniforme API aan clientapplicaties. Dit is waar GraphQL Federatie, en specifiek Schema Stitching, een rol speelt.
Wat is GraphQL Federatie?
GraphQL Federatie is een krachtige architectuur waarmee u één enkele, uniforme GraphQL API kunt bouwen vanuit meerdere onderliggende GraphQL-services (die vaak microservices vertegenwoordigen). Het stelt ontwikkelaars in staat om gegevens over verschillende services te bevragen alsof het één enkele graph is, wat de clientervaring vereenvoudigt en de noodzaak voor complexe orkestratielogica aan de clientzijde vermindert.
Er zijn twee primaire benaderingen voor GraphQL Federatie:
- Schema Stitching: Dit omvat het combineren van meerdere GraphQL-schema's in één enkel, uniform schema op de gateway-laag. Het is een eerdere aanpak en vertrouwt op bibliotheken om de combinatie van schema's en de delegatie van queries te beheren.
- Apollo Federation: Dit is een recentere en robuustere aanpak die gebruikmaakt van een declaratieve schemataal en een speciale queryplanner om het federatieproces te beheren. Het biedt geavanceerde functies zoals type-extensies, key-directieven en gedistribueerde tracing.
Dit artikel richt zich op Schema Stitching, en verkent de concepten, voordelen, beperkingen en praktische implementatie ervan.
Schema Stitching Begrijpen
Schema Stitching is het proces van het samenvoegen van meerdere GraphQL-schema's tot één enkel, samenhangend schema. Dit uniforme schema fungeert als een façade, die de complexiteit van de onderliggende services voor de client verbergt. Wanneer een client een verzoek doet aan het gestiched schema, stuurt de gateway het verzoek intelligent door naar de juiste onderliggende service(s), haalt de gegevens op en combineert de resultaten voordat ze aan de client worden geretourneerd.
Zie het zo: u heeft meerdere restaurants (services) die elk gespecialiseerd zijn in verschillende keukens. Schema Stitching is als een universeel menu dat alle gerechten van elk restaurant combineert. Wanneer een klant (client) bestelt van het universele menu, wordt de bestelling intelligent doorgestuurd naar de juiste restaurantkeukens, wordt het eten bereid en vervolgens gecombineerd tot één enkele levering voor de klant.
Sleutelconcepten in Schema Stitching
- Remote Schema's: Dit zijn de individuele GraphQL-schema's van elke onderliggende service. Elke service stelt zijn eigen schema beschikbaar, dat de gegevens en operaties definieert die het levert.
- Gateway: De gateway is de centrale component die verantwoordelijk is voor het aan elkaar stitchen van de remote schema's en het beschikbaar stellen van het uniforme schema aan de client. Het ontvangt clientverzoeken, stuurt ze door naar de juiste services en combineert de resultaten.
- Schema Samenvoegen: Dit is het proces van het combineren van de remote schema's tot één enkel schema. Dit omvat vaak het hernoemen van types en velden om conflicten te vermijden en het definiëren van relaties tussen types over verschillende schema's heen.
- Query Delegatie: Wanneer een client een verzoek doet aan het gestiched schema, moet de gateway het verzoek delegeren naar de juiste onderliggende service(s) om de gegevens op te halen. Dit omvat het vertalen van de query van de client naar een query die door de remote service kan worden begrepen.
- Resultaataggregatie: Nadat de gateway gegevens van de onderliggende services heeft opgehaald, moet het de resultaten combineren tot één enkel antwoord dat aan de client kan worden geretourneerd. Dit omvat vaak het transformeren van de gegevens om overeen te komen met de structuur van het gestiched schema.
Voordelen van Schema Stitching
Schema Stitching biedt verschillende overtuigende voordelen voor organisaties die een microservices-architectuur adopteren:
- Uniforme API: Biedt een enkele, consistente API voor clients, wat de gegevenstoegang vereenvoudigt en de noodzaak voor clients om rechtstreeks met meerdere services te communiceren vermindert. Dit resulteert in een schonere en intuïtievere ontwikkelaarservaring.
- Minder Complexiteit voor de Client: Clients hoeven alleen te communiceren met het uniforme schema, waardoor ze worden afgeschermd van de complexiteit van de onderliggende microservices-architectuur. Dit vereenvoudigt de client-side ontwikkeling en vermindert de hoeveelheid code die aan de clientzijde nodig is.
- Verhoogde Schaalbaarheid: Hiermee kunt u individuele services onafhankelijk schalen op basis van hun specifieke behoeften. Dit verbetert de algehele schaalbaarheid en veerkracht van het systeem. Bijvoorbeeld, een gebruikersservice die hoge belasting ervaart, kan worden geschaald zonder andere services zoals de productcatalogus te beïnvloeden.
- Verbeterde Onderhoudbaarheid: Bevordert modulariteit en scheiding van verantwoordelijkheden, waardoor het gemakkelijker wordt om individuele services te onderhouden en te evolueren. Wijzigingen in één service hebben minder kans om andere services te beïnvloeden.
- Geleidelijke Adoptie: Kan stapsgewijs worden geïmplementeerd, waardoor u geleidelijk kunt migreren van een monolithische architectuur naar een microservices-architectuur. U kunt beginnen met het aan elkaar stitchen van bestaande API's en vervolgens de monolith geleidelijk ontbinden in kleinere services.
Beperkingen van Schema Stitching
Hoewel Schema Stitching tal van voordelen biedt, is het belangrijk om op de hoogte te zijn van de beperkingen:
- Complexiteit: Het implementeren en beheren van schema stitching kan complex zijn, vooral in grote en complexe systemen. Zorgvuldige planning en ontwerp zijn essentieel.
- Prestatie-overhead: De gateway introduceert enige prestatie-overhead vanwege de extra laag van indirectie en de noodzaak om queries te delegeren en resultaten te aggregeren. Zorgvuldige optimalisatie is cruciaal om deze overhead te minimaliseren.
- Schema-conflicten: Er kunnen conflicten ontstaan bij het samenvoegen van schema's van verschillende services, vooral als ze dezelfde typenamen of veldnamen gebruiken. Dit vereist een zorgvuldig schemaontwerp en mogelijk het hernoemen van types en velden.
- Beperkte Geavanceerde Functies: In vergelijking met Apollo Federation mist Schema Stitching enkele geavanceerde functies zoals type-extensies en key-directieven, wat het uitdagender kan maken om relaties tussen types over verschillende schema's te beheren.
- Volwassenheid van Tooling: De tooling en het ecosysteem rond Schema Stitching zijn niet zo volwassen als die rond Apollo Federation. Dit kan het uitdagender maken om problemen op te sporen en op te lossen.
Praktische Implementatie van Schema Stitching
Laten we een vereenvoudigd voorbeeld doorlopen van hoe u Schema Stitching kunt implementeren met Node.js en de graphql-tools
bibliotheek (een populaire keuze voor schema stitching). Dit voorbeeld omvat twee microservices: een Gebruikersservice en een Productservice.
1. Definieer de Remote Schema's
Definieer eerst de GraphQL-schema's voor elk van de remote services.
Gebruikersservice (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,
};
Productservice (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. Creëer de Gateway Service
Creëer nu de gateway service die de twee schema's aan elkaar zal stitchen.
Gateway Service (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. Start de Services
U moet de Gebruikersservice en Productservice op verschillende poorten draaien. Bijvoorbeeld:
Gebruikersservice (poort 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'));
Productservice (poort 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. Query het Gestiched Schema
Nu kunt u het gestiched schema bevragen via de gateway (die op poort 4000 draait). U kunt een query als volgt uitvoeren:
query {
product(id: "101") {
id
name
price
user {
id
name
email
}
}
}
Deze query haalt het product met ID "101" op en haalt ook de bijbehorende gebruiker op van de Gebruikersservice, wat aantoont hoe Schema Stitching u in staat stelt om gegevens over meerdere services te bevragen in één enkele aanvraag.
Geavanceerde Schema Stitching Technieken
Naast het basisvoorbeeld zijn hier enkele geavanceerde technieken die kunnen worden gebruikt om uw Schema Stitching-implementatie te verbeteren:
- Schema Delegatie: Hiermee kunt u delen van een query delegeren naar verschillende services op basis van de opgevraagde gegevens. U kunt bijvoorbeeld de resolutie van een `User`-type delegeren naar de Gebruikersservice en de resolutie van een `Product`-type naar de Productservice.
- Schema Transformatie: Dit omvat het wijzigen van het schema van een remote service voordat het in het uniforme schema wordt gestiched. Dit kan handig zijn voor het hernoemen van types en velden, het toevoegen van nieuwe velden of het verwijderen van bestaande velden.
- Aangepaste Resolvers: U kunt aangepaste resolvers in de gateway definiëren om complexe gegevenstransformaties af te handelen of om gegevens van meerdere services op te halen en te combineren tot één enkel resultaat.
- Context Delen: Het is vaak nodig om contextinformatie te delen tussen de gateway en de remote services, zoals authenticatietokens of gebruikers-ID's. Dit kan worden bereikt door contextinformatie door te geven als onderdeel van het query-delegatieproces.
- Foutafhandeling: Implementeer robuuste foutafhandeling om fouten die optreden in de remote services netjes af te handelen. Dit kan het loggen van fouten, het retourneren van gebruiksvriendelijke foutmeldingen of het opnieuw proberen van mislukte verzoeken omvatten.
Kiezen tussen Schema Stitching en Apollo Federation
Hoewel Schema Stitching een haalbare optie is voor GraphQL Federatie, is Apollo Federation de populairdere keuze geworden vanwege de geavanceerde functies en verbeterde ontwikkelaarservaring. Hier is een vergelijking van de twee benaderingen:
Functie | Schema Stitching | Apollo Federation |
---|---|---|
Schema Definitie | Gebruikt bestaande GraphQL schemataal | Gebruikt een declaratieve schemataal met directieven |
Query Planning | Vereist handmatige query-delegatie | Automatische query-planning door de Apollo Gateway |
Type Extensies | Beperkte ondersteuning | Ingebouwde ondersteuning voor type-extensies |
Key Directieven | Niet ondersteund | Gebruikt @key directief om entiteiten te identificeren |
Gedistribueerde Tracing | Vereist handmatige implementatie | Ingebouwde ondersteuning voor gedistribueerde tracing |
Tooling en Ecosysteem | Minder volwassen tooling | Meer volwassen tooling en een grote community |
Complexiteit | Kan complex zijn om te beheren in grote systemen | Ontworpen voor grote en complexe systemen |
Wanneer kiezen voor Schema Stitching:
- U heeft bestaande GraphQL-services en wilt deze snel combineren.
- U heeft een eenvoudige federatie-oplossing nodig en vereist geen geavanceerde functies.
- U heeft beperkte middelen en wilt de overhead van het opzetten van Apollo Federation vermijden.
Wanneer kiezen voor Apollo Federation:
- U bouwt een groot en complex systeem met meerdere teams en services.
- U heeft geavanceerde functies nodig zoals type-extensies, key-directieven en gedistribueerde tracing.
- U wilt een robuustere en schaalbaardere federatie-oplossing.
- U geeft de voorkeur aan een meer declaratieve en geautomatiseerde benadering van federatie.
Praktijkvoorbeelden en Gebruiksscenario's
Hier zijn enkele praktijkvoorbeelden van hoe GraphQL Federatie, inclusief Schema Stitching, kan worden gebruikt:
- E-commerceplatform: Een e-commerceplatform zou GraphQL Federatie kunnen gebruiken om gegevens van meerdere services te combineren, zoals een productcatalogusservice, een gebruikersservice, een bestelservice en een betalingsservice. Dit stelt clients in staat om gemakkelijk alle informatie op te halen die ze nodig hebben om productdetails, gebruikersprofielen, bestelgeschiedenis en betalingsinformatie weer te geven.
- Socialmediaplatform: Een socialmediaplatform zou GraphQL Federatie kunnen gebruiken om gegevens te combineren van services die gebruikersprofielen, berichten, opmerkingen en likes beheren. Dit stelt clients in staat om efficiënt alle informatie op te halen die nodig is om het profiel van een gebruiker, hun berichten en de bijbehorende opmerkingen en likes weer te geven.
- Financiële Dienstverlening Applicatie: Een applicatie voor financiële dienstverlening zou GraphQL Federatie kunnen gebruiken om gegevens te combineren van services die rekeningen, transacties en investeringen beheren. Dit stelt clients in staat om gemakkelijk alle informatie op te halen die ze nodig hebben om rekeningsaldi, transactiegeschiedenis en investeringsportfolio's weer te geven.
- Content Management Systeem (CMS): Een CMS kan GraphQL Federatie benutten om gegevens uit verschillende bronnen te integreren, zoals artikelen, afbeeldingen, video's en door gebruikers gegenereerde inhoud. Dit zorgt voor een uniforme API om alle inhoud met betrekking tot een specifiek onderwerp of auteur op te halen.
- Zorgapplicatie: Integreer patiëntgegevens uit verschillende systemen zoals elektronische patiëntendossiers (EPD), laboratoriumresultaten en afspraakplanning. Dit biedt artsen één enkel toegangspunt tot uitgebreide patiëntinformatie.
Best Practices voor Schema Stitching
Volg deze best practices om een succesvolle Schema Stitching-implementatie te garanderen:
- Plan uw Schema Zorgvuldig: Voordat u begint met het aan elkaar stitchen van schema's, plan zorgvuldig de structuur van het uniforme schema. Dit omvat het definiëren van de relaties tussen types over verschillende schema's, het hernoemen van types en velden om conflicten te vermijden, en het overwegen van de algehele gegevenstoegangspatronen.
- Gebruik Consistente Naamgevingsconventies: Hanteer consistente naamgevingsconventies for types, velden en operaties in alle services. Dit helpt conflicten te voorkomen en maakt het gemakkelijker om het uniforme schema te begrijpen.
- Documenteer uw Schema: Documenteer het uniforme schema grondig, inclusief beschrijvingen van types, velden en operaties. Dit maakt het voor ontwikkelaars gemakkelijker om het schema te begrijpen en te gebruiken.
- Monitor de Prestaties: Monitor de prestaties van de gateway en de remote services om eventuele prestatieknelpunten te identificeren en aan te pakken. Gebruik tools zoals gedistribueerde tracing om verzoeken over meerdere services te volgen.
- Implementeer Beveiliging: Implementeer passende beveiligingsmaatregelen om de gateway en de remote services te beschermen tegen ongeautoriseerde toegang. Dit kan het gebruik van authenticatie- en autorisatiemechanismen omvatten, evenals inputvalidatie en outputcodering.
- Versioneer uw Schema: Naarmate u uw schema's evolueert, versioneer ze dan op de juiste manier om ervoor te zorgen dat clients oudere versies van het schema kunnen blijven gebruiken zonder dat er iets kapotgaat. Dit helpt om brekende wijzigingen te voorkomen en achterwaartse compatibiliteit te garanderen.
- Automatiseer de Implementatie: Automatiseer de implementatie van de gateway en de remote services om ervoor te zorgen dat wijzigingen snel en betrouwbaar kunnen worden geïmplementeerd. Dit helpt het risico op fouten te verminderen en de algehele wendbaarheid van het systeem te verbeteren.
Conclusie
GraphQL Federatie met Schema Stitching biedt een krachtige aanpak voor het bouwen van uniforme API's vanuit meerdere services in een microservices-architectuur. Door de kernconcepten, voordelen, beperkingen en implementatietechnieken te begrijpen, kunt u Schema Stitching benutten om de gegevenstoegang te vereenvoudigen, de schaalbaarheid te verbeteren en de onderhoudbaarheid te vergroten. Hoewel Apollo Federation is uitgegroeid tot een meer geavanceerde oplossing, blijft Schema Stitching een haalbare optie voor eenvoudigere scenario's of bij het integreren van bestaande GraphQL-services. Overweeg zorgvuldig uw specifieke behoeften en vereisten om de beste aanpak voor uw organisatie te kiezen.