Cloud Endpoints supporta la transcodifica del protocollo in modo che i client possano accedere all'API gRPC utilizzando HTTP/JSON. Extensible Service Proxy (ESP) transcodifica HTTP/JSON in gRPC.
Questa guida descrive:
- Come utilizzare le annotazioni nel file
.protoper specificare la conversione dei dati da HTTP/JSON a gRPC - Come eseguire il deployment del servizio in Endpoints per utilizzare questa funzionalità
- Dove trovare ulteriori informazioni di riferimento sulla progettazione e l'implementazione della transcodifica per i servizi gRPC
Si presuppone che tu abbia già completato i nostri tutorial su gRPC e che tu abbia familiarità con i concetti di base relativi agli endpoint per le API gRPC.
Progettare un'API compatibile con la transcodifica
La transcodifica comporta la mappatura delle richieste HTTP/JSON e dei relativi parametri ai metodi gRPC e ai relativi parametri e tipi restituiti. Per questo motivo, anche se è possibile mappare una richiesta HTTP/JSON a qualsiasi metodo API arbitrario, è utile farlo se l'API gRPC è strutturata in modo orientato alle risorse, proprio come una tradizionale API REST HTTP. In altre parole, progetti il servizio API in modo che utilizzi un numero ridotto
di metodi standard, corrispondenti ai verbi HTTP come GET e PUT,
che operano sulle risorse e sulle raccolte di risorse del servizio,
che a loro volta sono un tipo di risorsa. Questi metodi standard sono List,
Get, Create, Update e Delete.
Se necessario, l'API può avere anche alcuni metodi personalizzati non standard, anche se la mappatura non è così semplice.
Puoi scoprire molto di più sulla progettazione orientata alle risorse e sulle mappature di transcodifica standard nella guida alla progettazione delle API. Questa guida alla progettazione è lo standard di progettazione seguito in Google per la progettazione di API pubbliche come le API Cloud. Sebbene non sia necessario seguire questa guida per utilizzare la transcodifica gRPC, lo consigliamo vivamente. In particolare, le seguenti pagine possono aiutarti a comprendere questi principi di progettazione e ad aggiungere mappature di transcodifica utili ai tuoi metodi:
- Progettazione orientata alle risorse
- Metodi standard
- Metodi personalizzati
- Verbi HTTP: questa pagina fornisce ulteriori linee guida per le implementazioni dei metodi se devono essere accessibili tramite HTTP.
Potrebbe esserti utile anche la seguente pagina di riferimento:
- Riferimento alla regola HTTP: un riferimento completo alle regole di mappatura HTTP,
Nel resto di questo documento, utilizzerai l'esempio della libreria che hai utilizzato nei nostri
tutorial, che già utilizza questi principi.
La libreria contiene raccolte di "libri" che gli utenti possono
List, Get, Create o Delete.
Dove configurare la transcodifica
La transcodifica gRPC è abilitata per impostazione predefinita e puoi utilizzarla senza alcuna
configurazione. Segui le istruzioni per
il deployment di un servizio utilizzando la transcodifica.
Successivamente, quando invii una richiesta HTTP POST al percorso URL
GRPC_SERVICE_FULL_NAME/METHOD_NAME> con i valori dei campi del messaggio di richiesta del metodo (se presenti) come JSON nel corpo della richiesta HTTP, ESP invia il messaggio di richiesta al metodo gRPC appropriato. Nell'esempio precedente,
GRPC_SERVICE_FULL_NAME è il nome completo del tuo servizio gRPC e METHOD_NAME è il nome del metodo.
Ad esempio, se invii un POST all'URL ListShelves della libreria come segue:
curl -XPOST http://mydomain/endpoints.examples.bookstore.Bookstore/ListShelves
Riceverai un elenco aggiornato degli scaffali in formato JSON.
Tuttavia, in termini di progettazione dell'interfaccia HTTP, è fortemente preferibile configurare esplicitamente i mapping, come descritto nel resto di questo documento.
Lo standard di configurazione dell'API gRPC per la configurazione del servizio consente di specificare
esattamente come devono essere tradotti i dati da HTTP/JSON a gRPC. Per farlo, sono supportati due meccanismi: annotazioni dirette nel file .proto e in YAML come parte del file di configurazione dell'API gRPC. Per facilità di lettura e manutenzione, ti consigliamo di utilizzare le annotazioni proto.
Per ulteriori informazioni sulla configurazione YAML e su quando potrebbe essere necessario utilizzarla,
consulta
Configurazione della transcodifica in YAML.
Ecco un esempio che utilizza l'approccio consigliato di Bookstore:
// Returns a specific bookstore shelf.
rpc GetShelf(GetShelfRequest) returns (Shelf) {
// Client example - returns the first shelf:
// curl http://DOMAIN_NAME/v1/shelves/1
option (google.api.http) = { get: "/v1/shelves/{shelf}" };
}
...
// Request message for GetShelf method.
message GetShelfRequest {
// The ID of the shelf resource to retrieve.
int64 shelf = 1;
}
L'annotazione indica a ESP che l'invio di una richiesta HTTP GET
con l'URL http://mydomain/v1/shelves/1 chiama il metodo GetShelf()
del server gRPC, con un GetShelfRequest contenente l'ID scaffale richiesto shelf
(in questo caso, 1).
Aggiunta di mappature di transcodifica
Questa sezione descrive alcune annotazioni di mappatura aggiuntive dell'esempio
Bookstore. Nel campione Libreria sono presenti due file proto di esempio, in modo da poterlo implementare con o senza le mappature di transcodifica e confrontare le differenze nei file proto:
bookstore.proto: utilizzato nei tutorial di Endpoints e non dispone di mapping di transcodifica.http_bookstore.proto: sono stati aggiunti i binding di transcodifica.
Per una guida più completa alla specifica delle mappature di transcodifica, consulta Metodi standard, Metodi personalizzati e il riferimento alle regole HTTP.
Mappare un metodo List
Il metodo List è definito nel file .proto con il relativo tipo di risposta:
// Returns a list of all shelves in the bookstore. rpc ListShelves(google.protobuf.Empty) returns (ListShelvesResponse) { // Define HTTP mapping. // Client example (Assuming your service is hosted at the given 'DOMAIN_NAME'): // curl http://DOMAIN_NAME/v1/shelves option (google.api.http) = { get: "/v1/shelves" }; } ... message ListShelvesResponse { // Shelves in the bookstore. repeated Shelf shelves = 1; }
L'annotazione in grassetto specifica la mappatura HTTP per questo metodo.
option (google.api.http)specifica che questo metodo è un'annotazione di mappatura HTTP gRPC.getspecifica che questo metodo è mappato a una richiesta HTTPGET."/v1/shelves"è il modello di percorso URL (aggiunto al dominio del servizio) che la richiestaGETutilizza per chiamare questo metodo. Il percorso URL è noto anche come percorso della risorsa perché in genere specifica la "cosa" o la risorsa che vuoi utilizzare. In questo caso, tutte le risorse della sezione della libreria.
Ad esempio, se un client chiama questo metodo inviando un GET all'URL
http://mydomain/v1/shelves, ESP chiama il metodo gRPC
ListShelves(). Il backend gRPC restituisce quindi gli scaffali, che
ESP converte in formato JSON e restituisce al client.
Mappare un metodo Get
Il metodo GetShelf di Bookstore è definito nel file .proto con i relativi tipi di richiesta e risposta:
// Returns a specific bookstore shelf. rpc GetShelf(GetShelfRequest) returns (Shelf) { // Client example - returns the first shelf: // curl http://DOMAIN_NAME/v1/shelves/1 option (google.api.http) = { get: "/v1/shelves/{shelf}" }; } ... // Request message for GetShelf method. message GetShelfRequest { // The ID of the shelf resource to retrieve. int64 shelf = 1; } ... // A shelf resource. message Shelf { // A unique shelf id. int64 id = 1; // A theme of the shelf (fiction, poetry, etc). string theme = 2; }
L'annotazione in grassetto specifica la mappatura HTTP per questo metodo.
option (google.api.http)specifica che questo metodo è un'annotazione di mappatura HTTP gRPC.getspecifica che questo metodo è mappato a una richiesta HTTPGET."/v1/shelves/{shelf}"è il percorso URL della richiesta, come prima, ma specifica/v1/shelves/e poi{shelf}. Questa notazione con parentesi graffe indica a ESP che qualsiasi valore presente in{shelf}è il valore che deve fornire pershelfnel parametroGetShelfRequestdel metodo.
Se un client chiama questo metodo inviando un GET all'URL
http://mydomain/v1/shelves/4, ESP crea un
GetShelfRequest con un valore shelf pari a 4 e poi chiama il metodo gRPC
GetShelf(). Il backend gRPC restituisce quindi Shelf richiesto con
l'ID 4, che ESP converte in formato JSON e restituisce al
client.
Questo metodo richiede solo un valore del campo di richiesta fornito dal
client, shelf, che specifichi nel modello di percorso URL con la notazione "acquisizione" tra parentesi graffe. Se necessario per identificare la risorsa richiesta, puoi acquisire anche più parti dell'URL. Ad esempio, il metodo GetBook
richiede che il client specifichi sia l'ID scaffale sia l'ID libro nell'URL:
// Returns a specific book.
rpc GetBook(GetBookRequest) returns (Book) {
// Client example - get the first book from the second shelf:
// curl http://DOMAIN_NAME/v1/shelves/2/books/1
option (google.api.http) = { get: "/v1/shelves/{shelf}/books/{book}" };
}
...
// Request message for GetBook method.
message GetBookRequest {
// The ID of the shelf from which to retrieve a book.
int64 shelf = 1;
// The ID of the book to retrieve.
int64 book = 2;
}
Oltre a valori letterali e parentesi di acquisizione per i valori dei campi, i modelli di percorso URL possono utilizzare caratteri jolly per indicare che qualsiasi elemento in questa parte dell'URL deve essere acquisito. La notazione {shelf} utilizzata nell'esempio precedente è in realtà una
scorciatoia per {shelf=*}. Puoi scoprire di più sulle regole per i modelli di percorso nel riferimento alle regole HTTP.
Nel caso di questo tipo di metodo, non è specificato alcun corpo della richiesta HTTP. Puoi
trovare altre linee guida per la mappatura dei metodi Get, incluso l'utilizzoparametri di ricercay,
in Metodi standard.
Mappare un metodo Create
Il metodo CreateShelf della libreria viene mappato a POST HTTP.
// Creates a new shelf in the bookstore. rpc CreateShelf(CreateShelfRequest) returns (Shelf) { // Client example: // curl -d '{"theme":"Music"}' http://DOMAIN_NAME/v1/shelves option (google.api.http) = { post: "/v1/shelves" body: "shelf" }; } ... // Request message for CreateShelf method. message CreateShelfRequest { // The shelf resource to create. Shelf shelf = 1; } ... // A shelf resource. message Shelf { // A unique shelf id. int64 id = 1; // A theme of the shelf (fiction, poetry, etc). string theme = 2; }
option (google.api.http)specifica che questo metodo è un'annotazione di mappatura HTTP gRPC.postspecifica che questo metodo è mappato a una richiesta HTTPPOST."/v1/shelves"è il percorso URL della richiesta, come prima.body: "shelf"viene utilizzato nel corpo della richiesta HTTP per specificare la risorsa che vuoi aggiungere, in formato JSON.
Ad esempio, se un client ha chiamato questo metodo nel seguente modo:
curl -d '{"theme":"Music"}' http://DOMAIN_NAME/v1/shelves
ESP utilizza il corpo JSON per creare un valore Shelf con il tema
"Music" per CreateShelfRequest, quindi chiama il metodo gRPC CreateShelf(). Tieni presente che il client non fornisce il valore id per Shelf.
Gli ID scaffale del Bookstore vengono forniti dal servizio durante la creazione di un nuovo scaffale.
Fornisci questo tipo di informazioni agli utenti del tuo servizio nella documentazione dell'API.
Utilizzare il carattere jolly nel corpo
Il nome speciale * può essere utilizzato nel mapping del corpo per indicare che ogni campo non vincolato dal modello di percorso deve essere mappato al corpo della richiesta.
Ciò consente la seguente definizione alternativa del metodo CreateShelf.
// Creates a new shelf in the bookstore. rpc CreateShelf(CreateShelfRequest) returns (Shelf) { // Client example: // curl -d '{"shelf_theme":"Music", "shelf_size": 20}' http://DOMAIN_NAME/v1/shelves/123 option (google.api.http) = { post: "/v1/shelves/{shelf_id}" body: "*" }; } ... // Request message for CreateShelf method. message CreateShelfRequest { // A unique shelf id. int64 shelf_id = 1; // A theme of the shelf (fiction, poetry, etc). string shelf_theme = 2; // The size of the shelf int64 shelf_size = 3; }
option (google.api.http)specifica che questo metodo è un'annotazione di mappatura HTTP gRPC.postspecifica che questo metodo è mappato a una richiesta HTTPPOST."/v1/shelves/{shelf_id}"è il percorso URL della richiesta. Qualunque valore sia presente in{shelf_id}è il valore del camposhelf_idinCreateShelfRequest.body: "*"viene utilizzato nel corpo della richiesta HTTP per specificare tutti i campi della richiesta rimanenti, ad eccezione dishelf_idin questo esempio, ovveroshelf_themeeshelf_size. Per tutti i campi nel corpo JSON con questi due nomi, i valori verranno utilizzati nei campi corrispondenti diCreateShelfRequest.
Ad esempio, se un client ha chiamato questo metodo nel seguente modo:
curl -d '{"shelf_theme":"Music", "shelf_size": 20}' http://DOMAIN_NAME/v1/shelves/123
ESP utilizza il corpo JSON e il modello di percorso per creare un CreateShelfRequest{shelf_id: 123 shelf_theme: "Music" shelf_size: 20},
che poi utilizza per chiamare il metodo gRPC CreateShelf(). Per maggiori dettagli, vedi HttpRule.
Configurazione della transcodifica in YAML
Un approccio alternativo consiste nello specificare i mapping da HTTP a gRPC nel file YAML di configurazione dell'API gRPC anziché nel file .proto. Potresti dover configurare la transcodifica in un file YAML se hai una singola definizione API proto utilizzata in più servizi, con mapping diversi specificati per ogni servizio.
rules nella sezione http del file YAML specifica come mappare le richieste HTTP/JSON
ai metodi gRPC:
http:
rules:
...
#
# 'GetShelf' is available via the GET HTTP verb and '/shelves/{shelf}' URL
# path, where {shelf} is the value of the 'shelf' field of 'GetShelfRequest'
# protobuf message.
#
# Client example - returns the first shelf:
# curl http://DOMAIN_NAME/v1/shelves/1
#
- selector: endpoints.examples.bookstore.Bookstore.GetShelf
get: /v1/shelves/{shelf}
...
Un esempio più completo dell'utilizzo di questo approccio per il servizio Bookstore di esempio
si trova in
api_config_http.yaml.
Eseguire il deployment di un servizio che utilizza la transcodifica
Il deployment di un servizio gRPC che utilizza la transcodifica è molto simile a quello di qualsiasi altro servizio gRPC, con una differenza principale. Nei
tutorial, l'esempio necessario per accettare le richieste gRPC
dal client di esempio. Tuttavia, se vuoi che Bookstore accetti anche le richieste HTTP, devi eseguire una configurazione aggiuntiva per ESP. I client utilizzano il protocollo HTTP1.1 per inviare richieste JSON/HTTP a ESP, quindi ESP deve essere configurato per utilizzare SSL (la porta SSL può supportare entrambi i tipi di richieste) oppure deve avere una porta speciale abilitata per accettare queste chiamate. Il deployment è per il resto
in gran parte uguale a quello descritto nel tutorial per l'ambiente scelto.
Assicurati che le regole HTTP siano implementate
Se hai già scaricato l'esempio della libreria per i
tutorial, tieni presente che devi scaricare una
versione leggermente diversa del file .proto con annotazioni,
http_bookstore.proto.
Devi anche clonare il repository
googleapis da GitHub
prima di eseguire protoc, poiché hai bisogno di
annotations.proto
nel percorso di inclusione.
git clone https://github.com/googleapis/googleapis
GOOGLEAPIS_DIR=<your-local-googleapis-folder>
Poi crei un nuovo descrittore .pb da http_bookstore.proto quando
esegui il deployment
della configurazione in Endpoints:
protoc \
--include_imports \
--include_source_info \
--proto_path=${GOOGLEAPIS_DIR} \
--proto_path=. \
--descriptor_set_out=api_descriptor.pb \
http_bookstore.proto
Se utilizzi il metodo alternativo di configurazione dei mapping HTTP nel file YAML di configurazione dell'API gRPC, devi anche assicurarti che le regole pertinenti vengano implementate durante l'implementazione della configurazione in Endpoints. Per provare questa operazione con il servizio Bookstore, le regole di base si trovano nel file api_config.yaml e le regole HTTP nel file api_config_http.yaml:
gcloud endpoints services deploy api_descriptor.pb api_config.yaml api_config_http.yaml
Utilizzo di SSL
Se SSL è abilitato per la comunicazione tra i client e ESP,
i client possono utilizzare la stessa porta per effettuare chiamate gRPC o HTTP1.1. Puoi scoprire
come configurare SSL per un servizio Endpoints in
Abilitazione di SSL.
Specifica una porta per ESP per accettare chiamate SSL utilizzando il flag --ssl_port
nel file di configurazione di Google Kubernetes Engine (GKE) o il comando
docker run (Compute Engine/Docker).
args: [
"--http_port", "8080",
"--ssl_port", "443", # enable SSL port at 443 to serve https requests
"--backend", "grpc://127.0.0.1:8081", # gRPC backend.
"--service", "SERVICE_NAME",
"--rollout_strategy", "managed",
]
Configurazione di una porta HTTP1.1
Se non utilizzi SSL, devi configurare una porta separata per le richieste HTTP1.1
perché gRPC e HTTP1.1 non possono condividere la stessa porta senza SSL. Utilizza
il flag --http_port nel file di configurazione GKE o
il comando docker run per specificare una porta per
accettare le chiamate HTTP1.1. Se vuoi che ESP accetti anche le chiamate gRPC, devi utilizzare anche il flag --http2_port per specificare una porta gRPC.
args: [
"--http_port", "8080", # for HTTP 1.1
"--http2_port", "8090", # for gRPC
"--backend", "grpc://127.0.0.1:8081", # gRPC backend.
"--service", "SERVICE_NAME",
"--rollout_strategy", "managed",
]
Chiamare un servizio utilizzando la transcodifica
Questa sezione descrive la configurazione del servizio e come effettuare chiamate HTTP al servizio.
Configurazione del servizio
Si presuppone che tu abbia già completato i tutorial di base sul servizio gRPC per l'ambiente scelto e che tu disponga di un cluster GKE o di un'istanza Compute Engine per eseguire l'esempio.
- Innanzitutto, assicurati di aver eseguito il deployment della configurazione del servizio Bookstore abilitato per HTTP in Endpoints, come descritto in Assicurati che le regole HTTP siano implementate.
Esegui il deployment del backend e di ESP come descritto nel tutorial per la piattaforma che hai scelto, utilizzando il flag
--http_portper abilitare una porta per le richiesteHTTP1.1:- Deployment GKE: segui le istruzioni riportate in
Deployment dell'API di esempio e di ESP nel cluster,
assicurandoti che il flag
"--http_port"sia specificato nel file di configurazione GKE. - Deployment di Compute Engine: segui le istruzioni riportate in
Esecuzione dell'API di esempio e di ESP in un container Docker.
Assicurati che il flag
--http_portsia specificato nel comandodocker runquando esegui il container Docker ESP preconfigurato.
- Deployment GKE: segui le istruzioni riportate in
Deployment dell'API di esempio e di ESP nel cluster,
assicurandoti che il flag
Effettuare chiamate HTTP al servizio
- Ottieni l'indirizzo IP esterno del fornitore di servizi email e impostalo su
$ESP_IP. Invia la seguente richiesta HTTP con
curlcurl http://$ESP_IP/v1/shelves(o utilizza lo stesso URL con
https://se utilizzi SSL). Il server risponde con:{"shelves":[{"id":"1","theme":"Fiction"},{"id":"2","theme":"Fantasy"}]}Se l'output mostra una risposta binaria, controlla la configurazione della porta perché potresti raggiungere la porta HTTP2 anziché la porta HTTP.
Prova un metodo
Create.CreateShelfrichiede una chiave API, quindi devi creare una chiave per il tuo progetto e impostarla come$KEY. Chiama ora:curl -d '{"theme":"Music"}' http://$ESP_IP/v1/shelves?key=$KEYSe chiami di nuovo
GetShelves, dovresti visualizzare il nuovo scaffale.