Cloud Endpoints supporta la transcodifica di protocolli in modo che i client possano accedere all'API gRPC utilizzando HTTP/JSON. L'Extensible Service Proxy (ESP) transcodifica HTTP/JSON in gRPC.
Questa guida descrive:
- Come utilizzare le annotazioni nel file
.proto
per specificare la conversione di 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 sull'implementazione della transcodifica per i servizi gRPC
Si presume che tu abbia già completato i nostri tutorial gRPC e abbia familiarità con i concetti di base degli endpoint per le API gRPC.
Progettazione di 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 di reso. Per questo, anche se è possibile mappare una richiesta HTTP/JSON a qualsiasi metodo API arbitrario, è utile se l'API gRPC è strutturata in modo orientato alle risorse, proprio come un'API HTTP REST tradizionale. In altre parole, il servizio API viene progettato in modo da utilizzare 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ò anche avere alcuni metodi personalizzati non standard, sebbene questi non siano altrettanto semplici da mappare.
Puoi trovare ulteriori informazioni 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 nella progettazione di API pubbliche come le API Cloud. Anche se non è necessario seguire questa guida per utilizzare la transcodifica gRPC, ti consigliamo vivamente di utilizzarla. In particolare, le seguenti pagine possono aiutarti a comprendere questi principi di progettazione e ad aggiungere utili mappature di transcodifica ai tuoi metodi:
- Progettazione orientata alle risorse
- Metodi standard
- Metodi personalizzati
- Verbi HTTP: questa pagina fornisce ulteriori linee guida per l'implementazione dei metodi se l'accesso avviene tramite HTTP.
Potrebbe essere utile anche la seguente pagina di riferimento:
- Riferimento regola HTTP: un riferimento completo per le regole di mappatura HTTP,
Nel resto del documento, utilizzi l'esempio della Libreria che hai usato nei nostri
Tutorial, che utilizzano già questi principi.
La Libreria ha raccolte "scaffale" di risorse "libro", 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 eseguire il deployment di un servizio utilizzando la transcodifica.
Successivamente, quando invii una richiesta HTTP POST
al percorso dell'URL
GRPC_SERVICE_FULL_NAME/METHOD_NAME>
con
i valori del campo del messaggio di richiesta del metodo (se presenti) come JSON nel corpo della richiesta HTTP,
ESP invia il messaggio
della 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 elemento POST
all'URL ListShelves
della Libreria come segue:
curl -XPOST http://mydomain/endpoints.examples.bookstore.Bookstore/ListShelves
Riceverai un elenco aggiornato di scaffali in formato JSON.
Tuttavia, è preferibilmente preferibile in termini di progettazione dell'interfaccia HTTP configurare esplicitamente le mappature, come descritto nel resto di questo documento.
Lo standard di configurazione dell'API gRPC per la configurazione del servizio consente di specificare esattamente come i dati devono essere tradotti da HTTP/JSON a gRPC. A tale scopo, sono supportati due meccanismi: le annotazioni dirette nel file .proto
e il file YAML come parte del file di configurazione dell'API gRPC. Consigliamo di utilizzare le annotazioni proto
per semplificare la lettura e la manutenzione.
Per ulteriori informazioni sulla configurazione YAML e su quando potrebbe essere necessario, consulta Configurazione della transcodifica in YAML.
Ecco un esempio che utilizza l'approccio consigliato dalla Libreria:
// 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'esecuzione 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
In questa sezione vengono descritte alcune annotazioni di mappatura aggiuntive dell'esempio di Libreria. Nell'esempio della Libreria sono presenti due file proto
di esempio, che puoi utilizzare per il deployment, con o senza le mappature di transcodifica, e per confrontare le differenze nei file proto
:
bookstore.proto
: utilizzato nei tutorial di Endpoints e non dispone di mappature di transcodifica.http_bookstore.proto
: sono state aggiunte associazioni di transcodifica.
Per una guida più completa a specificare le mappature di transcodifica, consulta Metodi standard, Metodi personalizzati e Riferimento alle regole HTTP.
Mappare un metodo List
Il metodo List
viene 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 di questo metodo.
option (google.api.http)
specifica che questo metodo è un'annotazione di mappatura HTTP gRPC.get
specifica che questo metodo è mappato a una richiesta HTTPGET
."/v1/shelves"
è il modello di percorso dell'URL (aggiunto al dominio del tuo servizio) che la richiestaGET
utilizza per chiamare questo metodo. Il percorso dell'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 nostra libreria.
Ad esempio, se un client chiama questo metodo inviando GET
all'URL http://mydomain/v1/shelves
, ESP chiama il metodo gRPC ListShelves()
. Il backend gRPC restituisce quindi gli scaffali, che vengono convertiti in formato JSON e restituiti al client.
Mappare un metodo Get
Il metodo GetShelf
della Libreria viene definito nel file .proto
con i relativi tipi di
richieste e risposte:
// 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 di questo metodo.
option (google.api.http)
specifica che questo metodo è un'annotazione di mappatura HTTP gRPC.get
specifica che questo metodo è mappato a una richiesta HTTPGET
."/v1/shelves/{shelf}"
è il percorso dell'URL per la richiesta, come prima, ma specifica/v1/shelves/
e poi{shelf}
. Questa notazione tra parentesi graffe indica a ESP che qualsiasi valore in{shelf}
deve essere fornito pershelf
nel parametroGetShelfRequest
del 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
di 4
e poi chiama il metodo gRPC
GetShelf()
. Il backend gRPC restituisce quindi il Shelf
richiesto con l'ID 4
, che ESP converte in formato JSON e restituisce al client.
Questo metodo richiede che il client fornisca un solo valore di campo di richiesta, shelf
, che specifichi nel modello di percorso dell'URL con la notazione "capture" tra parentesi graffe. Puoi anche acquisire più parti dell'URL, se necessario, per identificare la risorsa richiesta. 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 ai valori letterali e alle parentesi graffe per i valori dei campi, i modelli di percorso dell'URL possono utilizzare i caratteri jolly per indicare che ogni elemento dell'URL deve essere acquisito. La notazione {shelf}
utilizzata nell'esempio precedente è in realtà
una scorciatoia per {shelf=*}
. Per scoprire di più sulle regole dei modelli di percorso, consulta il riferimento alle regole HTTP.
Nel caso di questo tipo di metodo, non è stato specificato un corpo della richiesta HTTP. Puoi trovare ulteriori linee guida per la mappatura dei metodi Get
, incluso l'utilizzo dei parametri di ricerca, in Metodi standard.
Mappare un metodo Create
Il metodo CreateShelf
della Libreria viene mappato a HTTP POST
.
// 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.post
specifica che questo metodo è mappato a una richiesta HTTPPOST
."/v1/shelves"
è il percorso dell'URL per la richiesta, come in precedenza.body: "shelf"
viene utilizzato nel corpo della richiesta HTTP per specificare la risorsa che vuoi aggiungere, in formato JSON.
Ad esempio, se un cliente chiama questo metodo in questo 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 CreateShelf()
gRPC. Tieni presente che il client non fornisce il valore id
per Shelf
.
Gli ID della libreria sono forniti dal servizio durante la creazione di una nuova sezione.
Fornisci questo tipo di informazioni agli utenti del tuo servizio nella documentazione dell'API.
Usa carattere jolly nel corpo
Il nome speciale *
può essere utilizzato nella mappatura del corpo per indicare che ogni campo non associato al modello del percorso deve essere mappato al corpo della richiesta.
In questo modo viene attivata 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.post
specifica che questo metodo è mappato a una richiesta HTTPPOST
."/v1/shelves/{shelf_id}"
è il percorso dell'URL per la richiesta. Qualunque valore in{shelf_id}
è il valore del camposhelf_id
inCreateShelfRequest
.body: "*"
viene utilizzato nel corpo della richiesta HTTP per specificare tutti i campi rimanenti della richiesta, ad eccezione dishelf_id
, che sonoshelf_theme
eshelf_size
. I valori di questi campi nel corpo JSON con questi due nomi verranno utilizzati nei campi corrispondenti diCreateShelfRequest
.
Ad esempio, se un cliente chiama questo metodo in questo 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}
, quindi lo utilizza per chiamare il metodo CreateShelf()
gRPC. Per i dettagli, vedi HttpRule.
Configurazione della transcodifica in YAML
Un approccio alternativo consente di specificare le mappature da HTTP a gRPC nel file YAML configurazione gRPC anziché nel file .proto
. Potresti dover configurare la transcodifica in un file YAML se hai una singola definizione dell'API proto
utilizzata in più servizi, con mappature diverse specificate per ogni servizio.
La sezione 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 Libreria di esempio è in api_config_http.yaml
.
Deployment di un servizio che utilizza la transcodifica
Eseguire il deployment di un servizio gRPC che utilizza la transcodifica è molto simile a eseguire il deployment di qualsiasi altro servizio gRPC, con una differenza importante. Nei tutorial, l'esempio necessario per accettare richieste gRPC dal client di esempio. Tuttavia, se vuoi che la Libreria accetti anche le richieste HTTP, devi eseguire una configurazione aggiuntiva per ESP. I client utilizzano il protocollo HTTP1.1
per inviare le richieste JSON/HTTP a ESP, quindi ESP deve essere configurato per l'utilizzo di SSL (la porta SSL può supportare entrambi i tipi di richiesta) o deve avere una porta speciale abilitata per accettare queste chiamate. In caso contrario, il deployment è sostanzialmente lo stesso del tutorial per l'ambiente scelto.
Assicurati che venga eseguito il deployment delle regole HTTP
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é ti serve annotations.proto
nel percorso di inclusione.
git clone https://github.com/googleapis/googleapis
GOOGLEAPIS_DIR=<your-local-googleapis-folder>
Quindi creerai un nuovo descrittore .pb
da http_bookstore.proto
durante 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 per configurare le mappature HTTP nel file YAML gRPC API, devi anche assicurarti che il deployment delle regole pertinenti venga eseguito quando esegui il deployment della configurazione in Endpoints. Per fare una prova con il servizio
Libreria, le regole di base si trovano nel file
api_config.yaml
,
mentre 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 tuoi 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 Abilitare SSL.
Specifica una porta in modo che ESP accetti le 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 per HTTP1.1
in corso...
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 di GKE oppure usa il comando docker run
per specificare una porta per accettare le chiamate HTTP1.1
. Se vuoi che ESP accetti 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",
]
Chiamata a un servizio mediante transcodifica
Questa sezione descrive la configurazione del servizio e come effettuare chiamate HTTP al servizio.
Configurazione del servizio
Questo presuppone che tu abbia già completato i tutorial di base di gRPC per l'ambiente scelto e che tu abbia un cluster GKE o un'istanza Compute Engine per eseguire l'esempio.
- Assicurati prima di tutto di aver eseguito il deployment della configurazione del servizio Libri abilitato per HTTP in Endpoints, come descritto in Eseguire il deployment delle regole HTTP.
Esegui il deployment del backend e dell'ESP come descritto nel tutorial per la piattaforma che hai scelto, utilizzando il flag
--http_port
per abilitare una porta perHTTP1.1
richieste:- Deployment GKE: segui le istruzioni in Deployment dell'API di esempio e di ESP nel cluster, assicurandoti che il flag
"--http_port"
sia specificato nel file di configurazione di GKE. - Deployment in Compute Engine: segui le istruzioni in Esecuzione dell'API e dell'ESP di esempio in un container Docker.
Assicurati che il flag
--http_port
sia specificato nel comandodocker run
durante l'esecuzione del container Docker ESP preconfigurato.
- Deployment GKE: segui le istruzioni in Deployment dell'API di esempio e di ESP nel cluster, assicurandoti che il flag
Effettuare chiamate HTTP al servizio
- Recupera l'indirizzo IP esterno dell'ESP e impostalo su
$ESP_IP
. Effettua la seguente richiesta HTTP con
curl
curl http://$ESP_IP/v1/shelves
In alternativa, 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é è possibile che tu stia raggiungendo la porta HTTP2 anziché la porta HTTP.
Prova con un metodo
Create
.CreateShelf
richiede 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=$KEY
Se chiami di nuovo
GetShelves
dovresti vedere la nuova sezione.