Architettura GraphQL e Microservice


176

Sto cercando di capire dove GraphQL è più adatto da utilizzare all'interno di un'architettura Microservice.

C'è un dibattito sull'avere solo 1 schema GraphQL che funziona come gateway API per inviare la richiesta ai microservizi di destinazione e forzare la loro risposta. I microservizi utilizzerebbero comunque il protocollo REST / Thrift per il pensiero comunicativo.

Un altro approccio è invece quello di avere più schemi GraphQL uno per microservizio. Avere un server gateway API più piccolo che instrada la richiesta al microservizio di destinazione con tutte le informazioni della richiesta + la query GraphQL.

1o approccio

Avere 1 Schema GraphQL come gateway API avrà un rovescio della medaglia in cui ogni volta che cambi input / output del tuo contratto microservizio, dobbiamo cambiare lo schema GraphQL di conseguenza sul lato API Gateway.

2 ° approccio

Se si utilizza lo schema GraphQL multiplo per microservizi, è logico in un modo perché GraphQL applica una definizione di schema e l'utente dovrà rispettare l'input / output fornito dal microservizio.

Domande

  • Trovi GraphQL la soluzione giusta per progettare l'architettura di microservizi?

  • Come progetteresti un gateway API con una possibile implementazione di GraphQL?

Risposte:


242

Sicuramente approccio n. 1.

Il fatto che i tuoi clienti parlino con più servizi GraphQL (come nell'approccio n. 2) vanifica in primo luogo lo scopo di utilizzare GraphQL in primo luogo, che è quello di fornire uno schema sui dati dell'intera applicazione per consentire il recupero in un singolo roundtrip.

Avere un'architettura nulla condivisa potrebbe sembrare ragionevole dal punto di vista dei microservizi, ma per il tuo codice lato client è un vero incubo, perché ogni volta che cambi uno dei tuoi microservizi, devi aggiornare tutti i tuoi client. Te ne pentirai sicuramente.

GraphQL e microservizi si adattano perfettamente, perché GraphQL nasconde il fatto che i client dispongano di un'architettura di microservizi. Dal punto di vista del back-end, si desidera dividere tutto in microservizi, ma dal punto di vista del front-end, si desidera che tutti i dati provengano da un'unica API. L'uso di GraphQL è il modo migliore che conosco che ti consente di fare entrambe le cose. Ti consente di suddividere il back-end in microservizi, fornendo comunque un'unica API a tutte le tue applicazioni e consentendo l'unione tra i dati di diversi servizi.

Se non vuoi usare REST per i tuoi microservizi, puoi ovviamente avere ognuno con la sua API GraphQL, ma dovresti comunque avere un gateway API. Il motivo per cui le persone usano i gateway API è rendere più gestibile la chiamata dei microservizi dalle applicazioni client, non perché si adatta bene al modello di microservizi.


2
@helfer: questo ha davvero senso :) grazie. Ho alcune domande in cima a questa splendida risposta. - Stai dicendo che GraphQL deve essere usato come gateway API? - Diciamo che ho un microservizio di ordine che espone un endpoint REST o GraphQL. Una volta finito, devo aggiornare lo schema GraphQL principale per riflettere esattamente gli stessi dati che il microservizio esporrà? Non suona la duplicazione o l'allontanamento dalla cultura del microservizio che dovrebbe essere distribuito indipendentemente? Eventuali modifiche a un microservizio devono essere riflesse / duplicate nello schema GraphQL principale?
Fabrizio Fenoglio,

13
@Fabrizio la cosa bella di GraphQL è che anche se l'API REST backend cambia, lo schema GraphQL può rimanere lo stesso, purché ci sia un modo per ottenere i dati che il servizio REST ha precedentemente esposto. Se espone più dati, il modo canonico per gestirlo è semplicemente aggiungere nuovi campi / tipi allo schema esistente. Le persone di Facebook che hanno creato GraphQL mi hanno detto che non hanno mai fatto un cambiamento radicale al loro schema in quattro anni. Tutte le modifiche apportate sono state additive, il che significa che i nuovi client potrebbero utilizzare la nuova funzionalità, mentre i vecchi client continuerebbero a funzionare.
aiutante

4
Destra! :) Grazie per averlo scritto! Ti sto seguendo su Medium e su github attraverso i repository di Apollo! I tuoi articoli e post sono molto preziosi! :) Continua così! Penso anche che un articolo medio con argomento GraphQL + Microservices sarà molto piacevole da leggere!
Fabrizio Fenoglio,

1
Grazie, lo terrò a mente. Sicuramente pianificherò di scrivere di GraphQL e Microservices ad un certo punto, ma probabilmente non nelle prossime due settimane.
aiutante

Che ne dici della combinazione dell'opzione # 2 e github.com/AEB-labs/graphql-weaver ?
Mohsen,

35

Leggi l'articolo qui , che spiega come e perché l'approccio n. 1 funziona meglio. Guarda anche l'immagine qui sotto presa dall'articolo che ho citato: inserisci qui la descrizione dell'immagine

Uno dei principali vantaggi di avere tutto dietro un singolo endpoint è che i dati possono essere instradati in modo più efficace rispetto a se ogni richiesta avesse il proprio servizio. Mentre questo è il valore spesso propagandato di GraphQL, una riduzione della complessità e del servizio si insinuano, la struttura dei dati risultante consente anche di definire la proprietà dei dati in modo estremamente ben definito e chiaramente delineato.

Un altro vantaggio dell'adozione di GraphQL è il fatto che si può fondamentalmente affermare un maggiore controllo sul processo di caricamento dei dati. Poiché il processo per i caricatori di dati va al proprio endpoint, è possibile onorare la richiesta in modo parziale, completo o con avvertenze e quindi controllare in modo estremamente granulare il modo in cui i dati vengono trasferiti.

Il seguente articolo spiega molto bene questi due vantaggi insieme ad altri: https://nordicapis.com/7-unique-benefits-of-using-graphql-in-microservices/


Ciao, scusa per le domande su Noob, ma il tuo gateway graphQL non è un nuovo punto di conservazione? Ad esempio, se ho un servizio basket improvvisamente sollecitato, il mio gateway graphQL non si spezzerebbe troppo? Fondamentalmente non sono sicuro del suo ruolo, questo gateway dovrebbe contenere molti resolver per ogni servizio?
Eric Burel,

1
@EricBurel Grazie per la domanda. In realtà, per quanto ho capito dall'articolo, tutti gli schemi di servizi diversi sono unificati in uno schema GraphQL, quindi, come hai detto, altri servizi sono ancora nei loro set di dati. Per quanto riguarda la possibilità di un'unica fonte di errore per il gateway graphQL, ci sono sempre altre opzioni come fornire un piano di backup. Per favore leggi questo articolo ( labs.getninjas.com.br/… ) per maggiori informazioni. Spero che questo ti aiuti.
Enayat,

Come testate il gateway API centrale e i singoli servizi? Stai facendo l'integrazione o deridendo la risposta http?
Jaime Sangcap,

7

Per l'approccio n. 2, in effetti è così che scelgo, perché è molto più semplice che mantenere manualmente il fastidioso gateway API. In questo modo puoi sviluppare i tuoi servizi in modo indipendente. Rendi la vita molto più semplice: P

Ci sono alcuni ottimi strumenti per combinare gli schemi in uno, ad esempio graphql-weaver e i graphql-tools di apollo , sto usando graphql-weaver, è facile da usare e funziona benissimo.


L'uso di GraphQL in Android è indispensabile per creare un file .graphql con tutte le query? O posso semplicemente crearli nel codice senza questo file?
Mauro Alessandro

1
@MauroAlexandro Non sono un ragazzo Android, ma puoi avere le domande in diversi file. È più un problema di progettazione. IMHO, preferisco il primo :)
HFX il

5

A partire dalla metà del 2019 la soluzione per il 1 ° Approccio ha ora il nome " Federazione Schema " coniata dal popolo Apollo (in precedenza questo era spesso indicato come cuciture GraphQL). Propongono anche i moduli @apollo/federatione @apollo/gatewayper questo.

AGGIUNGI: Si noti che con Schema Federation non è possibile modificare lo schema a livello di gateway. Quindi, per ogni bit di cui hai bisogno nel tuo schema, devi avere un servizio separato.


è anche valido sapere che questa soluzione richiede Apollo Server che è leggermente limitato nella versione gratuita (max 25 milioni di query al mese)
Marx,

0

A partire dal 2019 il modo migliore è scrivere microservizi che implementano le specifiche del gateway Apollo e quindi incollare questi servizi usando un gateway seguendo l'approccio n. 1. Il modo più veloce per costruire il gateway è un'immagine docker come questa Quindi utilizzare docker-compose per avviare contemporaneamente tutti i servizi:

version: '3'

services:
    service1:
        build: service1
    service2:
        build: service2
    gateway:
        ports:
            - 80:80
        image: xmorse/apollo-federation-gateway
        environment: 
            - CACHE_MAX_AGE=5
            - "FORWARD_HEADERS=Authorization, X-Custom-Header" # default is Authorization, pass '' to reset
            - URL_0=http://service1
            - URL_1=http://service2

0

Il modo in cui viene descritto in questa domanda, credo che l'uso di un gateway API personalizzato come servizio di orchestrazione possa avere molto senso per applicazioni complesse focalizzate sull'azienda. GraphQL può essere una buona scelta tecnologica per quel servizio di orchestrazione, almeno per quanto riguarda l'interrogazione. Il vantaggio del tuo primo approccio (uno schema per tutti i microservizi) è la possibilità di unire i dati di più microservizi in una singola richiesta. Ciò può o meno essere molto importante a seconda della situazione. Se la GUI richiede il rendering simultaneo di dati da più microservizi, questo approccio può semplificare il codice client in modo tale che una singola chiamata possa restituire dati adatti per l'associazione dei dati con gli elementi della GUI di tali framework come Angular o React. Questo vantaggio non si applica alle mutazioni.

Lo svantaggio è l'accoppiamento stretto tra le API dei dati e il servizio di orchestrazione. Le versioni non possono più essere atomiche. Se ti astieni dall'introdurre modifiche che si interrompono all'indietro nelle API dei tuoi dati, ciò può introdurre complessità solo quando ripristini un rilascio. Ad esempio, se stai per rilasciare nuove versioni di due API di dati con le corrispondenti modifiche nel servizio di orchestrazione e devi eseguire il rollback di una di queste versioni ma non dell'altra, sarai comunque costretto a ripristinare tutte e tre le versioni.

In questo confronto tra GraphQL e REST scoprirai che GraphQL non è altrettanto efficiente delle API RESTful, quindi non consiglierei di sostituire REST con GraphQL per le API dei dati.


0

Alla domanda 1, Intuit ha riconosciuto la potenza di GraphQL qualche anno fa quando ha annunciato il passaggio all'ecosistema API One Intuit ( https://www.slideshare.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integrations -quickbooks-connect-2017 ). Intuit ha scelto di seguire l'approccio 1. Lo svantaggio menzionato in realtà impedisce agli sviluppatori di introdurre modifiche allo schema che potrebbero potenzialmente interrompere le applicazioni client.

GraphQL ha contribuito a migliorare la produttività degli sviluppatori in vari modi.

  1. Durante la progettazione di un nuovo microservizio per un dominio, gli ingegneri (backend / frontend / stakeholder) concordano uno schema per le entità del dominio. Una volta approvato, lo schema viene unito allo schema del dominio principale (universale) e distribuito su Gateway. Gli ingegneri front end possono iniziare a codificare le applicazioni client con questo schema mentre gli ingegneri di backend implementano la funzionalità. Avere uno schema universale significa che non ci sono due microservizi con funzionalità ridondante.
  2. GraphQL ha aiutato le applicazioni client a diventare più semplici e veloci. Vuoi recuperare i dati da / aggiornare i dati a più microservizi? Tutto ciò che le applicazioni client devono fare è attivare UNA richiesta GraphQL e il livello di astrazione del gateway API si occuperà di recuperare e raccogliere dati da più fonti (microservizi). Framework open source come Apollo ( https://www.apollographql.com/ ) hanno accelerato il ritmo dell'adozione di GraphQL.

  3. Poiché il mobile è la prima scelta per le applicazioni moderne, è importante progettare requisiti di larghezza di banda dati inferiori da zero a terra. GraphQL aiuta consentendo alle app client di richiedere solo campi specifici.

Alla domanda 2: abbiamo creato un livello di astrazione personalizzato nel gateway API che sa quale parte dello schema è di proprietà di quale servizio (provider). Quando arriva una richiesta di query, il livello di astrazione inoltra la richiesta ai servizi appropriati. Una volta che il servizio sottostante restituisce la risposta, il livello di astrazione è responsabile della restituzione dei campi richiesti.

Tuttavia, oggi ci sono diverse piattaforme là fuori (server Apollo, graphql-yoga, ecc.) Che consentono di costruire uno strato di astrazione GraphQL in pochissimo tempo.


0

Ho lavorato con GraphQL e microservizi

In base alla mia esperienza, ciò che funziona per me è una combinazione di entrambi gli approcci a seconda della funzionalità / utilizzo, non avrò mai un singolo gateway come nell'approccio 1 ... ma non un graphql per ogni microservizio come approccio 2.

Ad esempio, in base all'immagine della risposta di Enayat, in questo caso farei 3 gateway grafici (non 5 come nell'immagine)

inserisci qui la descrizione dell'immagine

  • App (Prodotto, Carrello, Spedizione, Inventario, necessari / collegati ad altri servizi)

  • Pagamento

  • Utente

In questo modo è necessario prestare particolare attenzione alla progettazione dei dati minimi necessari / collegati esposti dai servizi dipendenti, come token di autenticazione, ID utente, ID pagamento, stato di pagamento

Nella mia esperienza, ad esempio, ho il gateway "Utente", in quel GraphQL ho le query / mutazioni dell'utente, login, accesso, disconnessione, modifica password, recupero e-mail, conferma e-mail, cancellazione account, modifica profilo, caricamento foto , ecc ... questo grafico da solo è abbastanza grande !, è separato perché alla fine gli altri servizi / gateway si preoccupano solo delle informazioni risultanti come userid, nome o token.

In questo modo è più facile ...

  • Ridimensionare / arrestare i diversi nodi gateway a seconda dell'utilizzo. (ad esempio le persone potrebbero non modificare sempre il proprio profilo o pagare ... ma la ricerca dei prodotti potrebbe essere utilizzata più frequentemente).

  • Una volta che un gateway matura, cresce, si conosce l'utilizzo o si ha più esperienza sul dominio è possibile identificare quali sono le parti dello schema che potrebbero avere il proprio gateway (... mi è successo con un enorme schema che interagisce con i repository git , Ho separato il gateway che interagisce con un repository e ho visto che l'unico input necessario / informazioni collegate era ... il percorso della cartella e il ramo previsto)

  • La cronologia dei tuoi repository è più chiara e puoi avere un repository / sviluppatore / team dedicato a un gateway e ai suoi microservizi coinvolti.

AGGIORNARE:

Ho un cluster di kubernetes online che sta usando lo stesso approccio che descrivo qui con tutti i backend usando GraphQL, tutti opensource, ecco il repository principale: https://github.com/vicjicaman/microservice-realm

Questo è un aggiornamento della mia risposta perché penso che sia meglio se il codice di risposta / approccio è sottoposto a backup del codice in esecuzione e può essere consultato / rivisto, spero che questo aiuti.


-3

Poiché l'architettura dei microservizi non ha una definizione corretta, non esiste un modello specifico per questo stile, ma la maggior parte di essi presenterà alcune caratteristiche notevoli. Nel caso dell'architettura dei microservizi, ogni servizio può essere suddiviso in singoli piccoli componenti, che possono essere ottimizzato e distribuito individualmente senza influire sull'integrità dell'applicazione. Ciò significa che puoi semplicemente modificare alcuni servizi senza ricorrere alla ridistribuzione dell'applicazione tramite lo sviluppo di app di microservizi personalizzati .


Anche se manca di una "definizione corretta", è un concetto ben compreso e chiaramente delimitato nel contesto della domanda. A parte questo, la tua risposta non affronta affatto la domanda.
Roy Prins,

-7

Maggiori informazioni sui microservizi, penso che GraphQL potrebbe funzionare perfettamente anche nell'architettura senza server. Non uso GraphQL ma ho un mio progetto simile . Lo uso come aggregatore che invoca e concentra molte funzioni in un unico risultato. Penso che potresti applicare lo stesso modello per GraphQL.


2
Siamo spiacenti, ma ciò non è affatto pertinente per la domanda del PO. La domanda riguarda due approcci specifici che utilizzano GraphQL. Potrebbe essere stato inserito meglio come commento.
tiomno,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.