gRPC サービスの構成

gRPC サービスを作成するには、API Gateway を使用しているかどうかにかかわらず、1 つ以上の proto ファイル(拡張子が .proto のテキスト ファイル)でインターフェース定義を指定します。proto ファイルでは、データ構造、メソッド、メソッド パラメータ、戻り値の型など、API のサーフェスを定義します。次に、言語に固有のプロトコル バッファ コンパイラ protoc を使用して proto ファイルをコンパイルします。詳細については、gRPC とはgRPC のコンセプトをご覧ください。

gRPC サービスを API Gateway で管理するには、コンパイルされた proto ファイルに加えて、1 つ以上の YAML ファイルでサービス構成を指定する必要があります。サービス構成とは、認証、割り当てなどの gRPC サービスの動作を定義するための仕様です。

サービス構成の概要

YAML ファイルの先頭には、名前やタイトルなどのサービスに関する基本情報を指定できます。YAML ファイルのサブセクションで、以下のようなサービス構成をします。

次に例を示します。

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

各サブセクションは通常、さまざまなサービス構成を行う .proto メッセージに対応しています。次に例を示します。

  • authentication: 呼び出し元の認証方法を指定します。
  • backend: リモート バックエンド ルーティングを制御します。
  • http: 1 つの RPC メソッドを 1 つ以上の HTTP REST API メソッドにマッピングする際のルールを定義します。
  • usage: API キー検証の有効、無効を選択できます。

サービス構成の公式なスキーマは、.proto メッセージ google.api.Service によって定義されます。

基本的な構成

API Gateway と Cloud Run for gRPC のスタートガイドチュートリアルで使用されている Bookstore サンプルには、基本インターフェース定義ファイルとサービス構成ファイルが含まれています。

Bookstore のインターフェース定義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 のサービス構成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

上記のコードサンプルは、次の機能を持つ最も単純なサービス構成です。

  • *.apigateway.PROJECT_ID.cloud.goog という名前のサービスを定義します。ここで、PROJECT_ID は Google Cloud プロジェクト ID の名前です。
  • bookstore.proto ファイルで定義されているように、サービスが API endpoints.examples.bookstore.Bookstore を公開することを指定します。

ルールとセレクタ

場合によっては、サービスの個々の要素に構成を関連付ける機能が必要になることがあります。たとえば、認証を特定のメソッドのみに適用し、他のメソッドには適用しない場合などです。サービス構成でこの構成をする場合、サービス構成の一部(authenticationhttp)でルールやセレクタを指定できます。セレクタは、ルールに関連付けられた構成が適用されるサービスの要素(メソッド名など)を識別します。

セレクタでは、サービス、メソッド、メッセージ、フィールド、列挙の完全修飾名や列挙値をカンマ区切りで指定します。名前の最後のセグメントをワイルドカード * にすることで、すべてのサフィックスを対象にできます。ワイルドカードは、パターンの末尾、および名前のセグメント全体についてのみ使用できます。たとえば、foo.* は有効ですが、foo.b*foo.*.bar は有効ではありません。該当するすべての要素のデフォルトを構成するには、* を単独で指定します。

例 1(サービス全体に適用)

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

例 2(単一のメソッドに適用)

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

上記の例は、ListShelves メソッドを除くすべてのメソッドで API キー検証を義務付ける方法を示しています。

ルールは順番に評価され、宣言の順序で最後に一致するルールが適用されます。

複数の YAML ファイルの使用

同じサービスの各機能を複数の YAML ファイルで構成しておくと便利な場合があります。複数の YAML ファイルを使用すると、ファイルの再利用や環境に応じてファイル内容の変更をすることが簡単になります。たとえば Bookstore サンプルでは、基本的な構成を api_config.yaml ファイルで、HTTP ルールを api_config_http.yaml ファイルでそれぞれ指定しています。これにより、Bookstore で JSON / HTTP から gRPC へのコード変換を有効にする場合にのみ HTTP ルールをデプロイできます。

サービス構成に複数の YAML ファイルを使用する場合、構成がデプロイされるときに各ファイルが google.api.Service proto メッセージに変換され、さらに proto マージ セマンティクスですべてのメッセージがマージされます。つまり、より後に出現するインスタンスの独特なスカラー フィールドはすべて、それ以前のものを置き換えます。したがって、同じルールについて 2 つのファイルで異なる特異値を指定した場合、構成のデプロイ時には、2 つ目のファイルで指定した値が使用されます。特異な埋め込みメッセージがマージされ、繰り返しフィールドが連結されます。

ルールと同様に、マージは設定の優先順に行われます。2 つのサービス構成がある場合、2 番目のサービス構成が 1 番目の構成をオーバーライドします。

アノテーション(HTTP ルールのみ)

HTTP オプションを構成する方法として、YAML ファイルを使用するほかに、proto ファイルでオプション メカニズムを使って直接構成することもできます。API アノテーションは annotations.proto で定義されています。

アノテーションは、プロトコル バッファ インターフェース定義のすべての使用事例で構成オプションが不変な場合に使われます。たとえば API の実装が 1 つだけの場合や、すべての実装で HTTP インターフェースを同じにする必要がある場合には、proto ファイルで HTTP 構成にアノテーションを付けることができます。

proto ファイルとサービス構成 YAML ファイルの両方で構成オプションが指定されている場合は、サービス構成がアノテーションをオーバーライドします。

proto ファイルのアノテーションの例:

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'

詳細については、HTTP / JSON の gRPC へのコード変換をご覧ください。

次のステップ