Cloud Endpoints unterstützt die Protokolltranscodierung, sodass Clients mit HTTP/JSON auf Ihre gRPC API zugreifen können. Der Extensible Service Proxy (ESP) transcodiert HTTP/JSON zu gRPC.
In diesem Leitfaden erfahren Sie:
- wie Sie Annotationen in der
.proto
-Datei verwenden, um eine Datenumwandlung von HTTP/JSON in gRPC anzugeben, - wie Sie den Dienst in Endpoints bereitstellen, um dieses Feature zu nutzen und
- wo Sie weitere Referenzinformationen zum Design und Implementieren der Transcodierung für gRPC-Dienste finden.
Dabei wird davon ausgegangen, dass Sie unsere Anleitungen für gRPC bereits durchgearbeitet haben und mit grundlegenden Konzepten von Endpoints für gRPC APIs vertraut sind.
Transcodierungstaugliche API entwerfen
Bei der Transcodierung werden die HTTP-/JSON-Anfragen und deren Parameter den gRPC-Methoden und deren Parametern und Rückgabetypen zugeordnet. Obwohl eine HTTP-/JSON-Anfrage jeder beliebigen API-Methode zugeordnet werden kann, fällt diese Zuordnung leichter, wenn die gRPC API genau wie eine herkömmliche HTTP REST API ressourcenorientiert strukturiert ist. Sie entwerfen den API-Dienst also so, dass er mithilfe einer kleinen Anzahl von Standardmethoden, die HTTP-Verben wie GET
und PUT
entsprechen, Vorgänge für die im Dienst enthaltenen Ressourcen und Sammlungen von Ressourcen ausführt, die selbst eine Art von Ressource sind. Diese Standardmethoden sind List
, Get
, Create
, Update
und Delete
.
Gegebenenfalls kann die API auch einige benutzerdefinierte Methoden enthalten, auch wenn es schwieriger ist, diese zuzuordnen.
In der API-Designanleitung finden Sie viele weitere Informationen zum ressourcenorientierten Design und zu den Standardzuordnungen für die Transcodierung. Diese Designanleitung ist der Designstandard, der Google-intern zum Entwerfen öffentlicher APIs wie Cloud APIs verwendet wird. Sie müssen dieser Anleitung zum Verwenden der gRPC-Transcodierung zwar nicht folgen, es wird jedoch dringend empfohlen. Insbesondere werden Ihnen die folgenden Seiten dabei helfen, diese Designgrundsätze zu verstehen und Ihre Methoden um nützliche Transcodierungszuordnungen zu ergänzen:
- Ressourcenorientiertes Design
- Standardmethoden
- Benutzerdefinierte Methoden
- HTTP-Verben: Diese Seite enthält zusätzliche Richtlinien für Ihre Methodenimplementierungen, wenn der Zugriff über HTTP erfolgen soll.
Die folgende Referenzseite könnte ebenfalls nützlich sein:
- HTTP-Regelreferenz: Eine umfassende Referenz für HTTP-Zuordnungsregeln.
Im weiteren Verlauf dieses Dokuments verwenden Sie wieder das Bookstore-Beispiel aus unseren Anleitungen, in dem diese Grundsätze bereits umgesetzt werden.
Der Bookstore hat "Shelf"-Sammlungen mit "Book"-Ressourcen, für die Nutzer List
-, Get
-, Create
- oder Delete
-Vorgänge ausführen können.
Wo kann die Transcodierung konfiguriert werden
Die gRPC-Transcodierung ist standardmäßig aktiviert, sodass Sie sie ohne jegliche Konfiguration verwenden können. Folgen Sie der Anleitung zum Bereitstellen eines Dienstes mithilfe von Transcodierung.
Wenn Sie anschließend eine HTTP-POST
-Anfrage an den URL-Pfad GRPC_SERVICE_FULL_NAME/METHOD_NAME>
senden und gegebenenfalls Feldwerte für die Anfragenachricht der Methode als JSON im HTTP-Anfragetext angeben, leitet der ESP die Anfragenachricht an die entsprechende gRPC-Methode weiter. Im vorherigen Beispiel ist GRPC_SERVICE_FULL_NAME
der vollständige Name Ihres gRPC-Dienstes und METHOD_NAME
der Name der Methode.
Wenn Sie beispielsweise diese POST
-Anfrage an die Bookstore-URL ListShelves
senden:
curl -XPOST http://mydomain/endpoints.examples.bookstore.Bookstore/ListShelves
erhalten Sie eine aktuelle Liste der Shelves im JSON-Format.
Die explizite Konfiguration von Zuordnungen ist jedoch im Hinblick auf das HTTP-Schnittstellendesign deutlich zu bevorzugen, wie im weiteren Verlauf dieses Dokuments beschrieben.
Mit dem gRPC API-Konfigurationsstandard für die Dienstkonfiguration können Sie genau festlegen, wie Daten von HTTP/JSON in gRPC zu übersetzen sind. Dabei werden zwei Mechanismen unterstützt: direkte Annotationen in der .proto
-Datei und in YAML als Teil der gRPC API-Konfigurationsdatei. Zur leichteren Lesbarkeit und Verwaltung empfehlen wir proto
-Annotationen.
Wie die YAML-Konfiguration genau aussieht und wann Sie sie möglicherweise verwenden müssen, finden Sie unter Transcodierung in YAML konfigurieren.
Im folgenden Beispiel wird der empfohlene Ansatz im Bookstore verwendet:
// 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;
}
Die Annotation teilt dem ESP mit, dass bei einer HTTP-GET
-Anfrage mit der URL http://mydomain/v1/shelves/1
die Methode GetShelf()
des gRPC-Servers aufgerufen wird. Der dafür verwendete Parameter GetShelfRequest
enthält die angeforderte Shelf-ID shelf
(in diesem Fall 1
).
Transcodierungszuordnungen hinzufügen
In diesem Abschnitt werden einige zusätzliche Zuordnungsannotationen aus dem Bookstore-Beispiel beschrieben. Das Bookstore-Beispiel enthält zwei proto
-Beispieldateien, sodass Sie es mit und ohne Transcodierungszuordnungen bereitstellen und die Unterschiede in den proto
-Dateien vergleichen können:
bookstore.proto
: Wird in den Anleitungen für Endpoints verwendet und enthält keine Transcodierungszuordnungen.http_bookstore.proto
: Transcodierungsbindungen wurden hinzugefügt.
Eine ausführlichere Anleitung zum Festlegen von Transcodierungszuordnungen finden Sie unter Standardmethoden, Benutzerdefinierte Methoden und in der HTTP-Regelreferenz.
Methode List
zuordnen
Die Methode List
wird in der .proto
-Datei mit zugehörigem Antworttyp definiert:
// 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; }
Die fett markierte Annotation legt die HTTP-Zuordnung für diese Methode fest.
option (google.api.http)
gibt an, dass diese Methode eine Annotation für die gRPC-zu-HTTP-Zuordnung ist.get
gibt an, dass diese Methode einer HTTP-GET
-Anfrage zugeordnet ist."/v1/shelves"
ist die URL-Pfadvorlage, die an die Domain Ihres Dienstes angehängt ist und von derGET
-Anfrage verwendet wird, um diese Methode aufzurufen. Der URL-Pfad wird auch als Ressourcenpfad bezeichnet, da er normalerweise die Ressource angibt, die Sie verwenden möchten. In diesem Fall sind dies alle Shelf-Ressourcen des Bookstores.
Wenn ein Client beispielsweise diese Methode durch Senden einer GET
-Anfrage an die URL http://mydomain/v1/shelves
aufruft, ruft der ESP die gRPC-Methode ListShelves()
auf. Das gRPC-Back-End gibt dann die Shelves zurück, die der ESP in das JSON-Format umwandelt und an den Client zurückgibt.
Methode Get
zuordnen
Die Methode GetShelf
des Bookstores ist in der .proto
-Datei mit zugehörigen Anfrage- und Antworttypen definiert:
// 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; }
Die fett markierte Annotation legt die HTTP-Zuordnung für diese Methode fest.
option (google.api.http)
gibt an, dass diese Methode eine Annotation für die gRPC-zu-HTTP-Zuordnung ist.get
gibt an, dass diese Methode einer HTTP-GET
-Anfrage zugeordnet ist."/v1/shelves/{shelf}"
ist wie oben der URL-Pfad für die Anfrage, gibt jedoch/v1/shelves/
und dann{shelf}
an. Diese Notation mit geschweiften Klammern weist den ESP an, alle in{shelf}
enthaltenen Elemente als Wert fürshelf
im MethodenparameterGetShelfRequest
bereitzustellen.
Wenn ein Client diese Methode durch Senden einer GET
-Anfrage an die URL http://mydomain/v1/shelves/4
aufruft, erstellt der ESP einen GetShelfRequest
-Parameter mit einem shelf
-Wert von 4
und ruft dann damit die gRPC-Methode GetShelf()
auf. Das gRPC-Back-End gibt dann die angeforderte Shelf
mit
die ID 4
, die vom ESP in das JSON-Format umgewandelt und an den
Client.
Bei dieser Methode muss der Client nur einen einzigen Anfragefeldwert (shelf
) bereitstellen, der in der URL-Pfadvorlage in geschweiften Klammern angegeben wird ("Aufnahme"-Notation). Sie können auch mehrere Teile der URL aufnehmen, wenn das zum Identifizieren der angeforderten Ressource nötig ist. Beispielsweise muss der Client bei der Methode GetBook
sowohl die Shelf-ID als auch die Book-ID in der URL angeben:
// 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;
}
Neben Literalen und geschweiften Klammern für Feldwerte können URL-Pfadvorlagen auch Platzhalter enthalten. Damit geben Sie an, dass alle Elemente in diesem Teil der URL aufgenommen werden sollen. Die im vorherigen Beispiel verwendete {shelf}
-Notation ist eigentlich ein Kürzel für {shelf=*}
. Weitere Informationen zu den Regeln für Pfadvorlagen finden Sie in der HTTP-Regelreferenz.
Bei diesem Methodentyp ist kein HTTP-Anfragetext angegeben. Weitere Anleitungen zum Zuordnen von Get
-Methoden, darunter zum Verwenden von Abfrageparametern, finden Sie unter Standardmethoden.
Methode Create
zuordnen
Die Methode CreateShelf
des Bookstores ist HTTP-POST
zugeordnet:
// 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)
gibt an, dass diese Methode eine Annotation für die gRPC-zu-HTTP-Zuordnung ist.post
gibt an, dass diese Methode einer HTTP-POST
-Anfrage zugeordnet ist."/v1/shelves"
ist wie oben der URL-Pfad für die Anfrage.body: "shelf"
wird im HTTP-Anfragetext verwendet, um die hinzuzufügende Ressource im JSON-Format anzugeben.
Wenn ein Client beispielsweise diese Methode so aufruft:
curl -d '{"theme":"Music"}' http://DOMAIN_NAME/v1/shelves
erstellt der ESP anhand des JSON-Textes einen Shelf
-Wert mit dem Thema "Music"
für den CreateShelfRequest
-Parameter und ruft dann die gRPC-Methode CreateShelf()
auf. Dabei stellt der Client keinen id
-Wert für Shelf
bereit.
Die Shelf-IDs des Bookstores werden vom Dienst bereitgestellt, wenn ein neues Shelf erstellt wird.
Diese Art von Information stellen Sie Nutzern Ihres Dienstes in der API-Dokumentation zur Verfügung.
Platzhalter im Text verwenden
Mit dem speziellen Namen *
* kann in der Textzuordnung angezeigt werden, dass jedes Feld, das nicht durch die Pfadvorlage gebunden ist, dem Anfragetext zugeordnet werden soll.
Dadurch wird die folgende alternative Definition der Methode CreateShelf
aktiviert.
// 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)
gibt an, dass diese Methode eine Annotation für die gRPC-zu-HTTP-Zuordnung ist.post
gibt an, dass diese Methode einer HTTP-POST
-Anfrage zugeordnet ist."/v1/shelves/{shelf_id}"
ist der URL-Pfad für die Anfrage. Alles, was sich in{shelf_id}
befindet, ist der Wert des Feldsshelf_id
inCreateShelfRequest
.body: "*"
wird im HTTP-Anfragetext verwendet, um alle verbleibenden Anfragefelder mit Ausnahme vonshelf_id
in diesem Beispiel anzugeben. In diesem Beispiel sind esshelf_theme
undshelf_size
. Die Werte in allen Feldern im JSON-Text mit diesen beiden Namen werden in den entsprechenden Feldern vonCreateShelfRequest
verwendet.
Wenn ein Client beispielsweise diese Methode so aufruft:
curl -d '{"shelf_theme":"Music", "shelf_size": 20}' http://DOMAIN_NAME/v1/shelves/123
Der ESP verwendet den JSON-Text und die Pfadvorlage, um eine CreateShelfRequest{shelf_id: 123 shelf_theme: "Music" shelf_size: 20}
zu erstellen und anschließend zum Aufrufen der gRPC-Methode CreateShelf()
zu verwenden. Weitere Informationen finden Sie unter HttpRule.
Transcodierung in YAML konfigurieren
Ein alternativer Ansatz besteht darin, die HTTP-zu-gRPC-Zuordnungen in der YAML-Datei für die gRPC API-Konfiguration und nicht in der .proto
-Datei anzugeben. Sie müssen die Transcodierung gegebenenfalls in einer YAML-Datei konfigurieren, wenn Sie eine einzelne proto
-API-Definition haben, die in mehreren Diensten mit unterschiedlichen Zuordnungen für jeden Dienst verwendet wird.
Die rules
im Abschnitt http
der YAML-Datei legen fest, wie HTTP-/JSON-Anfragen den gRPC-Methoden zugeordnet werden:
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}
...
Ein ausführlicheres Anwendungsbeispiel für diesen Ansatz finden Sie unter api_config_http.yaml
am Beispiel des Bookstore-Dienstes.
Dienst mit Transcodierung bereitstellen
Ein gRPC-Dienst, der Transcodierung verwendet, wird mit einem wesentlichen Unterschied größtenteils wie jeder andere gRPC-Dienst bereitgestellt. In den Anleitungen musste der Beispiel-Bookstore nur gRPC-Anfragen vom Beispielclient annehmen. Wenn der Bookstore jedoch auch HTTP-Anfragen annehmen soll, müssen Sie den ESP dafür speziell konfigurieren. Clients verwenden das Protokoll HTTP1.1
, um JSON-/HTTP-Anfragen an den ESP zu senden. Somit muss für den ESP entweder SSL konfiguriert (der SSL-Port unterstützt beide Anfragetypen) oder ein spezieller Port zur Annahme dieser Aufrufe aktiviert werden. Ansonsten erfolgt die Bereitstellung weitgehend so, wie sie in der Anleitung für Ihre Umgebung beschrieben ist.
Bereitstellung von HTTP-Regeln sicherstellen
Wenn Sie das Bookstore-Beispiel bereits für die Anleitungen heruntergeladen haben, müssen Sie noch eine etwas andere Version der .proto
-Datei mit Annotationen (http_bookstore.proto
) herunterladen.
Außerdem müssen Sie vor der protoc
-Ausführung das Repository googleapis
aus GitHub klonen, da Sie annotations.proto
im Include-Pfad benötigen:
git clone https://github.com/googleapis/googleapis
GOOGLEAPIS_DIR=<your-local-googleapis-folder>
Anschließend erstellen Sie einen neuen .pb
-Deskriptor aus http_bookstore.proto
, wenn Sie Ihre Konfiguration in Endpoints bereitstellen:
protoc \
--include_imports \
--include_source_info \
--proto_path=${GOOGLEAPIS_DIR} \
--proto_path=. \
--descriptor_set_out=api_descriptor.pb \
http_bookstore.proto
Wenn Sie die alternative Methode zum Konfigurieren von HTTP-Zuordnungen in der YAML-Datei für die gRPC API-Konfiguration verwenden, müssen Sie beim Bereitstellen der Konfiguration in Endpoints auch darauf achten, dass die relevanten Regeln vorhanden sind. Bei Verwendung dieser Methode mit dem Bookstore-Dienst geben Sie dafür die Datei api_config.yaml
mit den grundlegenden Regeln und die Datei api_config_http.yaml
mit den HTTP-Regeln an:
gcloud endpoints services deploy api_descriptor.pb api_config.yaml api_config_http.yaml
SSL verwenden
Wenn SSL für die Kommunikation zwischen den Clients und dem ESP aktiviert ist, können Clients denselben Port für gRPC- und HTTP1.1
-Aufrufe verwenden. Informationen zum Einrichten von SSL für einen Endpoints-Dienst finden Sie unter SSL aktivieren.
Mit dem Flag --ssl_port
können Sie in der Konfigurationsdatei für Google Kubernetes Engine (GKE) oder im Befehl docker run
(Compute Engine/Docker) einen Port für den ESP angeben, um SSL-Aufrufe anzunehmen:
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",
]
Port HTTP1.1
einrichten
Wenn Sie kein SSL verwenden, müssen Sie einen eigenen Port für HTTP1.1
-Anfragen einrichten, da gRPC und HTTP1.1
ohne SSL nicht denselben Port gemeinsam nutzen können. Verwenden Sie das Flag --http_port
in der GKE-Konfigurationsdatei oder im Befehl docker run
, um einen Port für die Annahme von HTTP1.1
-Aufrufen anzugeben. Falls der ESP auch gRPC-Aufrufe annehmen soll, müssen Sie außerdem mit dem Flag --http2_port
einen gRPC-Port angeben,
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",
]
Dienst mit Transkodierung aufrufen
In diesem Abschnitt wird beschrieben, wie Sie einen Dienst einrichten und HTTP-Aufrufe an den Dienst senden.
Dienst einrichten
In diesem Abschnitt wird davon ausgegangen, dass Sie die grundlegenden Anleitungen zu gRPC-Diensten für Ihre Umgebung bereits durchgearbeitet und einen GKE-Cluster oder eine Compute Engine-Instanz zum Ausführen des Beispiels eingerichtet haben.
- Prüfen Sie zuerst, ob Sie die HTTP-taugliche Bookstore-Dienstkonfiguration in Endpoints bereitgestellt haben, wie unter Bereitstellung von HTTP-Regeln gewährleisten beschrieben.
Stellen Sie das Backend und den ESP bereit, wie in der Anleitung für Ihre Plattform beschrieben. Geben Sie dazu das Flag
--http_port
an, um einen Port fürHTTP1.1
-Anfragen zu aktivieren:- GKE-Bereitstellung: Folgen Sie der Anleitung unter Beispiel-API und ESP im Cluster bereitstellen und prüfen Sie, ob das Flag
"--http_port"
in der GKE-Konfigurationsdatei angegeben ist. - Compute Engine-Bereitstellung: Folgen Sie der Anleitung unter Beispiel-API und ESP in einem Docker-Container ausführen.
Prüfen Sie, ob das Flag
--http_port
im Befehldocker run
angegeben ist, wenn Sie den vorkonfigurierten ESP-Docker-Container ausführen.
- GKE-Bereitstellung: Folgen Sie der Anleitung unter Beispiel-API und ESP im Cluster bereitstellen und prüfen Sie, ob das Flag
HTTP-Aufrufe an den Dienst senden
- Rufen Sie die externe IP-Adresse des ESP ab und legen Sie sie auf
$ESP_IP
fest. Senden Sie die folgende HTTP-Anfrage mit
curl
curl http://$ESP_IP/v1/shelves
(oder verwenden Sie dieselbe URL mit
https://
, wenn Sie SSL verwenden). Der Server antwortet mit:{"shelves":[{"id":"1","theme":"Fiction"},{"id":"2","theme":"Fantasy"}]}
Wenn eine binäre Antwort ausgegeben wird, prüfen Sie Ihre Portkonfiguration. Möglicherweise greifen Sie auf den HTTP2-Port und nicht den HTTP-Port zu.
Versuchen Sie es mit einer
Create
-Methode.CreateShelf
setzt einen API-Schlüssel voraus, sodass Sie für Ihr Projekt einen Schlüssel erstellen und als$KEY
festlegen müssen. Rufen Sie jetzt Folgendes auf:curl -d '{"theme":"Music"}' http://$ESP_IP/v1/shelves?key=$KEY
Wenn Sie
GetShelves
noch einmal aufrufen, sollten Sie das neue Shelf sehen.