gRPC-Dienst konfigurieren

Wenn Sie einen gRPC-Dienst erstellen, geben Sie unabhängig davon, ob Sie API Gateway verwenden, die Schnittstellendefinition in einer oder mehreren proto-Dateien an. Dies sind Textdateien mit der Erweiterung .proto. In proto-Dateien definieren Sie die Benutzeroberfläche Ihrer API, einschließlich Datenstrukturen, Methoden, Methodenparametern und Rückgabetypen. Anschließend kompilieren Sie die proto-Datei mit dem sprachspezifischen Protokollpuffer-Compiler protoc. In der Dokumentation zu gRPC finden sie eine Erläuterung zu gRPC und Informationen zu den gRPC-Konzepten.

Damit Ihr gRPC-Dienst von API Gateway verwaltet wird, müssen Sie neben der kompilierten .proto-Datei eine Dienstkonfiguration in einer oder mehreren YAML-Dateien angeben. In einer Dienstkonfiguration können Sie das Verhalten eines gRPC-Dienstes definieren, einschließlich Authentifizierung, Kontingenten usw.

Dienstkonfiguration – Übersicht

Am Anfang der YAML-Datei können Sie grundlegende Informationen zum Dienst angeben, z. B. seinen Namen und Titel. Andere Aspekte des Dienstes werden in Unterabschnitten der YAML-Datei konfiguriert, z. B.:

Beispiel:

type: google.api.Service
config_version: 3
name: calendar.googleapis.com
title: Google Calendar API
apis:
- name: google.calendar.v3.Calendar
authentication:
  providers:
  - id: google_calendar_auth
    jwks_uri: https://www.googleapis.com/oauth2/v1/certs
    issuer: https://securetoken.google.com
  rules:
  - selector: "*"
    requirements:
      provider_id: google_calendar_auth
backend:
  rules:
    - selector: "*"
      address: grpcs://my-service-98sdf8sd0-uc.a.run.app

Jeder Unterabschnitt entspricht normalerweise einer Nachricht vom Typ .proto message, in der Sie verschiedene Aspekte des Dienstes konfigurieren. Beispiel:

  • authentication: Gibt an, wie Aufrufer authentifiziert werden.
  • backend: steuert das Remote-Backend-Routing.
  • http: Definiert die Regeln für die Zuordnung einer RPC-Methode zu einer oder mehreren HTTP REST API-Methoden.
  • usage: Ermöglicht die selektive Aktivierung und Deaktivierung der Validierung von API-Schlüsseln.

Das offizielle Schema für die Dienstkonfiguration wird durch die .proto-Nachricht google.api.Service definiert.

Grundlegende Konfiguration

Das Bookstore-Beispiel, das in der Anleitung Erste Schritte mit API Gateway und Cloud Run für gRPC verwendet wird, enthält eine Datei mit einer grundlegenden Schnittstellendefinition und eine Dienstkonfigurationsdatei.

Bookstore-Schnittstellendefinition bookstore.proto:

syntax = "proto3";

package endpoints.examples.bookstore;

option java_multiple_files = true;
option java_outer_classname = "BookstoreProto";
option java_package = "com.google.endpoints.examples.bookstore";

import "google/protobuf/empty.proto";

service Bookstore {
  rpc ListShelves(google.protobuf.Empty) returns (ListShelvesResponse) {}
  rpc CreateShelf(CreateShelfRequest) returns (Shelf) {}
  rpc GetShelf(GetShelfRequest) returns (Shelf) {}
  rpc DeleteShelf(DeleteShelfRequest) returns (google.protobuf.Empty) {}
  rpc ListBooks(ListBooksRequest) returns (ListBooksResponse) {}
  rpc CreateBook(CreateBookRequest) returns (Book) {}
  rpc GetBook(GetBookRequest) returns (Book) {}
  rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {}
}

message Shelf {
  int64 id = 1;
  string theme = 2;
}

message Book {
  int64 id = 1;
  string author = 2;
  string title = 3;
}

Bookstore-Dienstkonfiguration api_config.yaml:

type: google.api.Service
config_version: 3

name: *.apigateway.PROJECT_ID.cloud.goog

title: Bookstore gRPC API
apis:
- name: endpoints.examples.bookstore.Bookstore

Das letzte Codebeispiel ist die einfachste Dienstkonfiguration:

  • Sie definiert einen Dienst mit dem Namen *.apigateway.PROJECT_ID.cloud.goog, wobei PROJECT_ID für Ihre Google Cloud-Projekt-ID steht.
  • Sie legt fest, dass der Dienst die API endpoints.examples.bookstore.Bookstore gemäß Definition in der Datei bookstore.proto bereitstellt.

Regeln und Auswahlen

Mitunter muss die Konfiguration einzelnen Elementen eines Diensts zugeordnet werden, um beispielsweise die Authentifizierung für bestimmte Methoden zu erzwingen. Um dies in Ihrer Dienstkonfiguration zu konfigurieren, können Sie in einigen Teilen der Dienstkonfiguration, z. B. authentication und http, Regeln und Selektoren angeben. Ein Selektor identifiziert die Elemente des Dienstes, z. B. einen Methodennamen, auf die die mit der Regel verbundene Konfiguration angewendet wird.

Ein Selektor ist eine durch Kommas getrennte Liste mit qualifizierten Namen, die im Dienst definiert wurden: Methoden, Nachrichten, Felder, Enumerationen oder Enumerationswerte. Das letzte Segment des Namens kann der Platzhalter * sein, der für ein beliebiges Suffix steht. Platzhalter sind nur am Ende eines Namens und nur für ein ganzes Segment des Namens zulässig. Beispiel: foo.* ist zulässig, aber nicht foo.b* oder foo.*.bar. Wenn Sie für alle anwendbaren Elemente einen Standardwert konfigurieren möchten, geben Sie nur * an.

Beispiel 1 (wirkt sich auf den gesamten Dienst aus):

usage:
  rules:
  # Allow unregistered calls for all methods.
  - selector: "*"
    allow_unregistered_calls: true

Beispiel 2 (wirkt sich auf eine einzelne Methode aus):

usage:
  rules: # IMPORTANT: ONLY LAST MATCHING RULE IS APPLIED
  # Disable API key validation on just the ListShelves method
  # while requiring an API key for the rest of the API.
  - selector: "*"
    allow_unregistered_calls: false
  - selector: "endpoints.examples.bookstore.BookStore.ListShelves"
    allow_unregistered_calls: true

Das letzte Beispiel zeigt, wie die Validierung der API-Schlüssel für alle Methoden außer der Methode ListShelves vorausgesetzt wird.

Regeln werden sequenziell ausgewertet. Angewendet wird die letzte übereinstimmende Regel in der Deklarationsreihenfolge.

Mehrere YAML-Dateien verwenden

Es kann sinnvoll sein, mehr als eine YAML-Datei zu verwenden, um verschiedene Funktionen für denselben Dienst zu konfigurieren. Wenn Sie mehrere YAML-Dateien verwenden, können Sie Dateien leichter wiederverwenden und für verschiedene Umgebungen anpassen. Im oben aufgeführten Bookstore-Beispiel wird die grundlegende Konfiguration beispielsweise in der Datei api_config.yaml festgelegt. Die HTTP-Regeln werden in der Datei api_config_http.yaml angegeben. Dadurch können Sie die HTTP-Regeln nur bereitstellen, wenn Sie JSON/HTTP für die gRPC-Transcodierung für den Bookstore aktivieren möchten.

Wenn Sie für die Dienstkonfiguration mehrere YAML-Dateien verwenden, werden beim Bereitstellen der Konfiguration alle Dateien in .proto-Nachrichten vom Typ google.api.Service konvertiert. Anschließend erfolgt die Zusammenführung aller Nachrichten mit der entsprechenden Semantik für .proto-Dateien. Dies bedeutet, dass alle einzelnen skalaren Felder in letzterer Instanz die Felder in der vorherigen Instanz ersetzen. Wenn Sie daher für dieselbe Regel in zwei Dateien unterschiedliche Singulärwerte angeben, wird für die Bereitstellung der Konfiguration der Wert in der zweiten Datei verwendet. Außerdem werden einzelne eingebettete Nachrichten zusammengeführt und sich wiederholende Felder verkettet.

Wie bei Regeln wird auch bei Zusammenführungen die Reihenfolge berücksichtigt. Wenn zwei Dienstkonfigurationen vorhanden sind, überschreibt die zweite Dienstkonfiguration die erste.

Annotationen (nur HTTP-Regeln)

Alternativ zu einer YAML-Datei können Sie HTTP-Optionen mithilfe des Optionsmechanismus auch direkt in der proto-Datei konfigurieren. API-Annotationen werden in annotations.proto definiert.

Nutzen Sie Annotationen, wenn die Konfigurationsoption bei allen Verwendungen der API-Definition für den Protokollzwischenspeicher unverändert bleiben soll. Wenn eine API beispielsweise nur einmal implementiert wurde oder alle Implementierungen dieselbe HTTP-Oberfläche benötigen, kann die HTTP-Konfiguration in der proto-Datei annotiert werden.

Wenn sowohl in der proto-Datei als auch in der YAML-Dienstkonfigurationsdatei eine Konfigurationsoption angegeben ist, überschreibt die YAML-Konfiguration die Annotation.

Beispielannotation in einer proto-Datei:

rpc ListShelves(google.protobuf.Empty) returns (ListShelvesResponse) {
    option (google.api.http) = { get: "/v1/shelves" };
}


# The preceding annotation is equivalent to the following service configuration:

http:
  rules:
  - selector: endpoints.examples.bookstore.BookStore.ListShelves
    get: '/v1/shelves'

Weitere Informationen finden Sie unter HTTP/JSON zu gRPC transcodieren.

Nächste Schritte