L'API REST è stata a lungo un pilastro della programmazione web. Ma recentemente GRPC ha iniziato a invadere il suo territorio. Si scopre che ci sono alcune ottime ragioni per questo. In questo tutorial, imparerai a conoscere i dettagli di gRPC e come si confronta con REST.
Una delle maggiori differenze tra REST e gRPC è il formato del payload. I messaggi REST in genere contengono JSON. Questo non è un requisito rigoroso e in teoria è possibile inviare qualsiasi cosa come risposta, ma in pratica l'intero ecosistema REST - inclusi strumenti, best practice ed esercitazioni - è incentrato su JSON. È sicuro affermare che, con pochissime eccezioni, le API REST accettano e restituiscono JSON.
gRPC, d'altra parte, accetta e restituisce messaggi Protobuf. Discuterò la forte digitazione in seguito, ma solo dal punto di vista delle prestazioni, Protobuf è un formato molto efficiente e ricco. JSON, d'altra parte, è un formato testuale. Puoi comprimere JSON, ma poi perdi il vantaggio di un formato testuale che puoi facilmente aspettarti.
Confrontiamo i protocolli di trasferimento utilizzati da REST e gRPC. REST, come accennato in precedenza, dipende pesantemente da HTTP (in genere HTTP 1.1) e dal modello richiesta-risposta. D'altra parte, gRPC utilizza il più recente protocollo HTTP / 2.
Ci sono diversi problemi che affliggono HTTP 1.1 che risolve HTTP / 2. Qui ci sono i più importanti.
HTTP 1.0 RFC 1945 è un RFC di 60 pagine. HTTP 1.1 è stato originariamente descritto in RFC 2616, che ha generato fino a 176 pagine. Tuttavia, in seguito, IETF lo ha diviso in sei documenti diversi: RFC 7230, 7231, 7232, 7233, 7234 e 7235, con un conteggio delle pagine combinato ancora più elevato. HTTP 1.1 consente molte parti opzionali che contribuiscono alle sue dimensioni e complessità.
La tendenza delle pagine web è quella di aumentare sia la dimensione totale della pagina (1,9 MB in media) sia il numero di oggetti sulla pagina che richiedono richieste individuali. Poiché ogni oggetto richiede una richiesta HTTP separata, questa moltiplicazione di oggetti separati aumenta significativamente il carico sui server Web e rallenta i tempi di caricamento delle pagine per gli utenti.
HTTP 1.1 è sensibile alla latenza. È richiesto un handshake TCP per ogni singola richiesta e un numero più elevato di richieste comporta un notevole aumento del tempo necessario per caricare una pagina. Il continuo miglioramento della larghezza di banda disponibile non risolve questi problemi di latenza nella maggior parte dei casi.
La limitazione del numero di connessioni allo stesso dominio (utilizzate solo 2, oggi 6-8) riduce significativamente la possibilità di inviare più richieste in parallelo.
Con il pipelining HTTP, è possibile inviare una richiesta in attesa della risposta a una richiesta precedente, creando effettivamente una coda. Ma questo introduce altri problemi. Se la tua richiesta rimane bloccata da una richiesta lenta, il tuo tempo di risposta ne risentirà.
Ci sono altre preoccupazioni come le penalità relative alle prestazioni e alle risorse quando si cambiano le linee. Al momento, il pipelining HTTP non è ampiamente abilitato.
HTTP / 2, che è uscito da SPDY di Google, mantiene le premesse e i paradigmi di base di HTTP:
http: //
e https: //
Schemi URLMa le parti opzionali di HTTP 1.1 sono state rimosse.
Per indirizzare il protocollo di negoziazione a causa dello schema di URL condiviso, esiste un'intestazione di aggiornamento. Inoltre, ecco uno shock per te: il protocollo HTTP / 2 è binario! Se sei stato su protocolli Internet, allora sai che i protocolli testuali sono considerati re perché sono più facili da risolvere per gli umani e costruire manualmente le richieste. Ma, in pratica, la maggior parte dei server oggi utilizza comunque crittografia e compressione. L'inquadratura binaria è molto importante per ridurre la complessità della gestione dei frame in HTTP 1.1.
Tuttavia, il miglioramento principale di HTTP / 2 è che utilizza flussi multiplex. Una singola connessione HTTP / 2 TCP può supportare molti flussi bidirezionali. Questi flussi possono essere interlacciati (senza fare la coda) e più richieste possono essere inviate contemporaneamente senza la necessità di stabilire nuove connessioni TCP per ognuna. Inoltre, i server possono ora inviare notifiche ai client tramite la connessione stabilita (HTTP / 2 push).
REST è un'interessante API. È costruito molto strettamente su HTTP. Non utilizza solo HTTP come trasporto, ma include tutte le sue funzionalità e crea un framework concettuale coerente su di esso. In teoria, suona alla grande. In pratica, è stato molto difficile implementare REST correttamente.
Non fraintendetemi: REST ha avuto e ha molto successo, ma la maggior parte delle implementazioni non aderisce completamente alla filosofia REST e utilizza solo un sottoinsieme dei suoi principi. Il motivo è che in realtà è piuttosto difficile mappare la logica e le operazioni aziendali nel rigoroso mondo REST.
Il modello concettuale utilizzato da gRPC è quello di avere servizi con interfacce chiare e messaggi strutturati per richieste e risposte. Questo modello si traduce direttamente dai concetti del linguaggio di programmazione come interfacce, funzioni, metodi e strutture dati. Permette anche a gRPC di generare automaticamente librerie client per te.
REST supporta solo il modello richiesta-risposta disponibile in HTTP 1.x. Ma GRPC sfrutta appieno le capacità di HTTP / 2 e ti consente di trasmettere informazioni costantemente. Esistono diversi tipi di streaming.
Il server invia un flusso di risposte dopo aver ricevuto un messaggio di richiesta del client. Dopo aver inviato tutte le risposte, i dettagli di stato del server e i metadati finali facoltativi vengono nuovamente inviati sul lato server. Il client viene completato una volta che ha tutte le risposte del server.
Il client invia un flusso di richieste multiple al server. Il server restituisce una singola risposta, in genere ma non necessariamente dopo che ha ricevuto tutte le richieste del client, insieme ai suoi dettagli di stato e ai metadati finali facoltativi.
In questo scenario, il client e il server inviano informazioni reciprocamente in forma praticamente libera (tranne che il client avvia la sequenza). Alla fine, il client chiude la connessione.
Il paradigma REST non impone alcuna struttura per il carico utile scambiato. In genere è JSON. I consumatori non hanno un meccanismo formale per coordinare il formato delle richieste e delle risposte. Il JSON deve essere serializzato e convertito nel linguaggio di programmazione target sia lato server che lato client. La serializzazione è un altro passo della catena che introduce la possibilità di errori e sovraccarico delle prestazioni.
Il contratto di servizio gRPC ha messaggi fortemente tipizzati che vengono convertiti automaticamente dalla loro rappresentazione Protobuf al linguaggio di programmazione scelto sia sul server che sul client.
JSON, d'altra parte, è teoricamente più flessibile perché è possibile inviare dati dinamici e non è necessario rispettare una struttura rigida.
Il supporto per gRPC nel browser non è così maturo. Oggi gRPC viene utilizzato principalmente per servizi interni che non sono esposti direttamente al mondo.
Se si desidera utilizzare un servizio GRPC da un'applicazione Web o da una lingua non supportata da gRPC, quindi gRPC offre un gateway API REST per esporre il servizio. Il plug-in del gateway gRPC genera un server API REST completo con un proxy inverso e la documentazione Swagger.
Con questo approccio, perdi la maggior parte dei vantaggi di gRPC, ma se devi fornire l'accesso a un servizio esistente, puoi farlo senza implementare il tuo servizio due volte.
Nel mondo dei microservizi, GRPC diventerà dominante molto presto. I vantaggi in termini di prestazioni e la facilità di sviluppo sono semplicemente troppo buoni per essere abbandonati. Tuttavia, non commettere errori, REST sarà ancora in giro per molto tempo. Eccelle ancora per le API pubblicamente esposte e per ragioni di compatibilità con le versioni precedenti.