Cloud Endpoints supporta la transcodifica del protocollo in modo che i client possano accedere API gRPC mediante HTTP/JSON. Extensible Service Proxy (ESP) transcodifica HTTP/JSON in gRPC.
Questa guida descrive:
- Come utilizzare le annotazioni nel file
.proto
per specificare la conversione dei dati da 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 transcodifica per servizi gRPC
Si presume che tu abbia già completato i nostri tutorial su gRPC e che tu abbia familiarità con i concetti di base degli endpoint per le API gRPC.
Progettazione di un'API adatta alla transcodifica
La transcodifica prevede la mappatura delle richieste HTTP/JSON e dei relativi parametri ai metodi gRPC e ai loro parametri e tipi di ritorno. Per questo motivo, anche se è possibile mappare una richiesta HTTP/JSON a qualsiasi metodo API arbitrario, è consigliabile farlo se l'API gRPC è strutturata in modo orientato alle risorse, proprio come un'API HTTP
REST tradizionale. In altre parole, progetti il servizio API in modo che utilizzi un numero ridotto
dei metodi standard, corrispondenti ai verbi HTTP come GET
e PUT
,
che operano sulle risorse e sulle raccolte di risorse del servizio,
che sono a loro volta 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, non sono così semplici da mappare.
Puoi scoprire molto di più sulla progettazione orientata alle risorse mappature di transcodifica nella guida alla progettazione delle API. Questa guida alla progettazione è lo standard di progettazione seguito da Google durante la progettazione di API pubbliche come 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 viene tramite HTTP.
Potrebbe essere utile anche la seguente pagina di riferimento:
- Riferimento alle regole HTTP: un riferimento completo per le 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 ha una "scaffale" raccolte di "libro" che gli utenti possono usare
List
, Get
, Create
o Delete
.
Dove configurare la transcodifica
La transcodifica gRPC è abilitata per impostazione predefinita e puoi utilizzarla senza
configurazione. Segui le istruzioni per implementare un servizio che utilizza la transcodifica.
Successivamente, quando invii una richiesta POST
HTTP al percorso dell'URL
GRPC_SERVICE_FULL_NAME/METHOD_NAME>
con
(se presenti) del campo del messaggio di richiesta del metodo come JSON nel corpo della richiesta HTTP,
ESP invia la richiesta
al metodo gRPC
appropriato. Nell'esempio precedente,
GRPC_SERVICE_FULL_NAME
è il nome completo del 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 delle sezioni in formato JSON.
Tuttavia, in termini di progettazione dell'interfaccia HTTP, è fortemente preferibile configurare esplicitamente le mappature, come descritto nel resto di questo documento.
Lo standard di configurazione dell'API gRPC per la configurazione del servizio ti 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 nell'ambito del file di configurazione dell'API gRPC. Ti consigliamo di utilizzare le annotazioni proto
per semplificare la lettura e la manutenzione.
Per ulteriori informazioni sulla configurazione YAML e
quando potresti aver bisogno di utilizzarla,
vedi
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 effettuare una richiesta GET
HTTP
con l'URL http://mydomain/v1/shelves/1
chiama GetShelf()
del server gRPC
con un elemento 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 della Libreria
campione. Nell'esempio di Bookstore sono presenti due file proto
di esempio, in modo da poterli implementare sia con che senza le mappature di transcodifica e confrontare le differenze nei file proto
:
bookstore.proto
: viene utilizzato nei tutorial di Endpoints e non ha mappature di transcoding.http_bookstore.proto
: associazioni di transcodifica aggiunte.
Per una guida più completa su come specificare le mappature di transcodifica, consulta Metodi standard, Metodi personalizzati e il riferimento alle regole HTTP.
Mappa 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 mapping HTTP gRPC annotazione.get
specifica che questo metodo è mappato a una richiesta HTTPGET
."/v1/shelves"
è il modello di percorso dell'URL (aggiunto al dominio del servizio) utilizzato dalla richiestaGET
per chiamare questo metodo. Il percorso dell'URL è noto anche come percorso della risorsa, perché in genere specifica "thing" o risorsa che vuoi utilizzare. In questo caso, tutte le risorse della sezione del nostro Negozio di libri.
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,
ESP converte in formato JSON e restituisce il client.
Mappa un metodo Get
Il metodo GetShelf
della libreria è 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 il mapping HTTP per questo metodo.
option (google.api.http)
specifica che questo metodo è un mapping HTTP gRPC annotazione.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 con parentesi graffa ESP che qualsiasi cosa sia in{shelf}
è il valore che dovrebbe indicashelf
nel parametroGetShelfRequest
del metodo.
Se un client chiama questo metodo inviando un GET
all'URL
http://mydomain/v1/shelves/4
, ESP crea un'istanza
GetShelfRequest
con un valore shelf
di 4
, quindi chiama il metodo gRPC
GetShelf()
. Il backend gRPC restituisce quindi l'oggetto Shelf
richiesto con
l'ID 4
, che ESP converte in formato JSON e restituisce
di alto profilo.
Questo metodo richiede solo che il client fornisca un singolo valore del campo della richiesta, shelf
, che specifichi nel modello di percorso dell'URL con la notazione "di acquisizione" tra parentesi graffe. Puoi anche acquisire più parti dell'URL
se necessario per identificare
la risorsa richiesta. Ad esempio, 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 caratteri jolly per indicare che qualsiasi elemento in questa parte dell'URL
acquisite. La notazione {shelf}
utilizzata nell'esempio precedente è in realtà una
scorciatoia per {shelf=*}
. Puoi scoprire di più sulle regole per il percorso
modelli nel
Riferimento per le regole HTTP.
In questo tipo di metodo, non è specificato il corpo della richiesta HTTP. Puoi trovare altre linee guida per la mappatura dei metodi Get
, incluso l'utilizzo dei parametri di query, in Metodi standard.
Mappa 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 mapping HTTP gRPC annotazione.post
specifica che questo metodo è mappato a una richiesta HTTPPOST
."/v1/shelves"
è il percorso dell'URL per la richiesta, come prima.body: "shelf"
viene utilizzato nel corpo della richiesta HTTP per specificare la risorsa da aggiungere in formato JSON.
Ad esempio, se un client chiama questo metodo come segue:
curl -d '{"theme":"Music"}' http://DOMAIN_NAME/v1/shelves
ESP usa il corpo JSON per creare un valore Shelf
con il tema
"Music"
per CreateShelfRequest
, quindi chiama gRPC CreateShelf()
. Tieni presente che il client non fornisce il valore id
per Shelf
.
Gli ID scaffale della Libreria vengono forniti dal servizio quando viene creato un nuovo scaffale.
Fornisci questo tipo di informazioni agli utenti del tuo servizio nella documentazione dell'API.
Utilizzare un carattere jolly nel corpo
Il nome speciale *
può essere utilizzato nella mappatura del corpo per indicare che ogni campo non associato dal modello di percorso deve essere mappato al corpo della richiesta.
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 mapping HTTP gRPC annotazione.post
specifica che questo metodo è mappato a una richiesta HTTPPOST
."/v1/shelves/{shelf_id}"
è il percorso dell'URL per la richiesta. Qualsiasi valore in{shelf_id}
è il valore del camposhelf_id
inCreateShelfRequest
.body: "*"
viene utilizzato nel corpo della richiesta HTTP per specificare tutti i campi della richiesta rimanenti, ad eccezione dishelf_id
in questo esempio, ovveroshelf_theme
eshelf_size
. Per tutti i campi del corpo JSON con questi due nomi, i relativi valori verranno utilizzati nei campi corrispondenti diCreateShelfRequest
.
Ad esempio, se un client chiama questo metodo come segue:
curl -d '{"shelf_theme":"Music", "shelf_size": 20}' http://DOMAIN_NAME/v1/shelves/123
ESP usa il corpo JSON e il modello di percorso per creare CreateShelfRequest{shelf_id: 123 shelf_theme: "Music" shelf_size: 20}
,
e quindi lo utilizza per chiamare il metodo gRPC CreateShelf()
. Per maggiori dettagli, consulta HttpRule.
Configurazione della transcodifica in YAML
Un approccio alternativo consiste nel specificare le mappature 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 dell'API proto
utilizzata in più servizi, con mappature diverse specificate per ciascun servizio.
Il rules
nella sezione http
del tuo file YAML specifica come mappare HTTP/JSON
richieste 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 di utilizzo di questo approccio per il servizio di libreria di esempio
è in
api_config_http.yaml
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 sostanziale. Nei tutorial, l'esempio doveva accettare le richieste gRPC dal client di esempio. Tuttavia, se vuoi che la libreria accetti anche le richieste HTTP, devi eseguire un'ulteriore configurazione per ESP. I client utilizzano il protocollo HTTP1.1
per inviare richieste JSON/HTTP all'ESP, pertanto l'ESP deve essere configurato per utilizzare SSL (la porta SSL può supportare entrambi i tipi di richiesta) o deve avere una porta speciale abilitata per accettare queste chiamate. Il deployment è in altro modo
in gran parte uguale a quello 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 le annotazioni,
http_bookstore.proto
.
Devi inoltre clonare
Repository googleapis
da GitHub
prima di eseguire protoc
, in quanto
annotations.proto
nel percorso di inclusione.
git clone https://github.com/googleapis/googleapis
GOOGLEAPIS_DIR=<your-local-googleapis-folder>
Quindi crei un nuovo descrittore .pb
da http_bookstore.proto
quando
deployment
la configurazione a 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 della configurazione dell'API gRPC, devi anche assicurarti che le regole pertinenti vengano implementate durante il deployment della configurazione in Endpoints. Per provare questa operazione con il servizio Libreria, le relative 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 l'ESP,
i client possono utilizzare la stessa porta per effettuare chiamate gRPC o HTTP1.1
. Puoi visualizzare
scopri come configurare SSL per un servizio Endpoints
Attivazione di SSL.
Specifica una porta per consentire a ESP di accettare le chiamate SSL utilizzando --ssl_port
nel file di configurazione di Google Kubernetes Engine (GKE) o
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",
]
Configurare 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 le funzionalità di
il flag --http_port
nel file di configurazione GKE
docker run
per specificare una porta su
accetta chiamate HTTP1.1
. Se vuoi anche che ESP accetti 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 tramite transcodifica
Questa sezione descrive la configurazione del servizio e come effettuare chiamate HTTP al servizio.
Configurazione del servizio
Si presume che tu abbia già completato i tutorial di base sul servizio gRPC per l'ambiente scelto e che tu abbia un cluster GKE o 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 Verificare il deployment delle regole HTTP.
Esegui il deployment del backend e dell'ESP come descritto nel tutorial per la piattaforma scelta, utilizzando il flag
--http_port
per attivare una porta per le richiesteHTTP1.1
:- Deployment GKE: segui le istruzioni in
Esegui il deployment dell'API e di ESP di esempio nel cluster.
e assicurarsi che il flag
"--http_port"
sia specificato di configurazione GKE. - Deployment di Compute Engine: segui le istruzioni riportate in Eseguire l'API e l'ESP di esempio in un contenitore Docker.
Assicurati che il flag
--http_port
sia specificato nel comandodocker run
durante l'esecuzione del container Docker ESP predefinito.
- Deployment GKE: segui le istruzioni in
Esegui il deployment dell'API e di ESP di esempio nel cluster.
e assicurarsi che il flag
Effettuare chiamate HTTP al servizio
- Ottieni l'indirizzo IP esterno dell'ESP e impostalo su
$ESP_IP
. Effettua la seguente richiesta HTTP con
curl
curl http://$ESP_IP/v1/shelves
(oppure 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 visualizza una risposta binaria, controlla la configurazione della porta. perché potresti aver raggiunto la porta HTTP2 anziché la porta HTTP.
Prova un metodo
Create
.CreateShelf
richiede una chiave API, quindi devi crearla 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 il tuo nuovo scaffale.