gRPC JSON コード変換用に HTTP と JSON を構成する

作成者: James Newton-King

gRPC JSON コード変換では、gRPC メソッドから RESTful JSON Web API を作成します。 RESTful API から gRPC メソッドにマップする方法をカスタマイズするために、注釈とオプションを使用します。

HTTP ルール

gRPC メソッドでコード変換をサポートするには、事前に gRPC メソッドに HTTP ルールで注釈を付ける必要があります。 HTTP ルールには、HTTP メソッドやルートなど、gRPC メソッドを RESTful API として呼び出すことに関する情報が含まれています。

import "google/api/annotations.proto";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/v1/greeter/{name}"
    };
  }
}

HTTP ルールは次のとおりです。

  • gRPC メソッドの注釈。
  • 名前 google.api.http によって識別されます。
  • google/api/annotations.proto ファイルからインポートされます。 google/api/http.proto および google/api/annotations.proto ファイルがプロジェクト内に存在する必要があります。

Note

通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。

HTTP メソッド

HTTP メソッドは、一致する HTTP メソッド フィールド名へのルートを設定することによって指定します。

  • get
  • put
  • post
  • delete
  • patch

custom フィールドでは、他の HTTP メソッドを使用できます。

次の例では、CreateAddress メソッドは指定したルートを持つ POST にマップされます。

service Address {
  rpc CreateAddress (CreateAddressRequest) returns (CreateAddressReply) {
    option (google.api.http) = {
      post: "/v1/address",
      body: "*"
    };
  }
}

ルート

gRPC JSON コード変換のルートでは、ルート パラメーターがサポートされます。 たとえば、ルート内の {name} は要求メッセージの name フィールドにバインドされます。

入れ子になったメッセージにフィールドをバインドするには、フィールドへのパスを指定します。 次の例では、{params.org}IssueParams メッセージの org フィールドにバインドされます。

service Repository {
  rpc GetIssue (GetIssueRequest) returns (GetIssueReply) {
    option (google.api.http) = {
      get: "/{apiVersion}/{params.org}/{params.repo}/issue/{params.issueId}"
    };
  }
}

message GetIssueRequest {
  int32 api_version = 1;
  IssueParams params = 2;
}
message IssueParams {
  string org = 1;
  string repo = 2;
  int32 issueId = 3;
}

コード変換ルートと ASP.NET Core ルートには、同様の構文と機能のセットがあります。 ただし、一部の ASP.NET Core ルーティング機能は、コード変換でサポートされていません。 これには以下が含まれます。

要求本文

コード変換では、要求本文の JSON が要求メッセージに逆シリアル化されます。 body フィールドで、HTTP 要求本文を要求メッセージにマップする方法を指定します。 値は、値を HTTP 要求本文にマップする要求フィールドの名前か、すべての要求フィールドをマップすることを示す * のいずれかです。

次の例では、HTTP 要求本文が address フィールドに逆シリアル化されます。

service Address {
  rpc AddAddress (AddAddressRequest) returns (AddAddressReply) {
    option (google.api.http) = {
      post: "/{apiVersion}/address",
      body: "address"
    };
  }
}

message AddAddressRequest {
  int32 api_version = 1;
  Address address = 2;
}
message Address {
  string street = 1;
  string city = 2;
  string country = 3;
}

クエリ パラメーター

ルート パラメーターまたは要求本文によってバインドされていない要求メッセージ内のフィールドは、HTTP クエリ パラメーターを使用して設定できます。

service Repository {
  rpc GetIssues (GetIssuesRequest) returns (GetIssuesReply) {
    option (google.api.http) = {
      get: "/v1/{org}/{repo}/issue"
    };
  }
}

message GetIssuesRequest {
  string org = 1;
  string repo = 2;
  string text = 3;
  PageParams page = 4;
}
message PageParams {
  int32 index = 1;
  int32 size = 2;
}

前の例の場合:

  • org および repo フィールドはルート パラメーターからバインドされます。
  • text や、page から入れ子になったフィールドなどの他のフィールドは、次のクエリ文字列からバインドできます: ?text=value&page.index=0&page.size=10

応答本文

既定では、コード変換で応答メッセージ全体が JSON としてシリアル化されます。 response_body フィールドを使用すると、応答メッセージのサブセットをシリアル化できます。

service Address {
  rpc GetAddress (GetAddressRequest) returns (GetAddressReply) {
    option (google.api.http) = {
      get: "/v1/address/{id}",
      response_body: "address"
    };
  }
}

message GetAddressReply {
  int32 version = 1;
  Address address = 2;
}
message Address {
  string street = 1;
  string city = 2;
  string country = 3;
}

前の例では、address フィールドが JSON として応答本文にシリアル化されます。

仕様

gRPC コード変換のカスタマイズの詳細については、HttpRule の仕様に関するページを参照してください。

JSON のカスタマイズ

メッセージは、Protobuf 仕様に含まれる JSON マッピングを使用して JSON との間で変換されます。 Protobuf の JSON マッピングは、JSON と Protobuf の間で変換するための標準化された方法であり、すべてのシリアル化はこれらの規則に従います。

ただし、gRPC JSON コード変換では、次の表に示すように、JSON を GrpcJsonSettings でカスタマイズするための制限されたオプションがいくつか提供されています。

オプション 既定値 説明
IgnoreDefaultValues false true に設定すると、シリアル化中に既定値を持つフィールドが無視されます。
WriteEnumsAsIntegers false true に設定すると、列挙型の値が文字列ではなく整数として書き出されます。
WriteInt64sAsStrings false true に設定すると、Int64 および UInt64 の値が数値ではなく文字列として書き出されます。
WriteIndented false true に設定すると、JSON が再フォーマットを使用して書き出されます。 このオプションは、行区切りの JSON メッセージを書き出し、再フォーマットを使用できないストリーミング メソッドには影響しません。
builder.Services.AddGrpc().AddJsonTranscoding(o =>
{
    o.JsonSettings.WriteIndented = true;
});

.proto ファイル内で json_name フィールド オプションを使用すると、JSON としてシリアル化されるときにフィールドの名前をカスタマイズできます。次に例を挙げます。

message TestMessage {
  string my_field = 1 [json_name="customFieldName"];
}

コード変換では、高度な JSON カスタマイズはサポートされていません。 JSON の構造を精密に制御する必要のあるアプリでは、ASP.NET Core Web API の使用をご検討ください。

その他の資料