はじめに
HTTP のステータスコードとは別に gRPC にもステータスコードの概念があるようだったので調べたことのメモです。
gRPC として用意されているステータスコード
ドキュメントは下記でした。
詳細はドキュメントに書いてありますが、 0-16 のコードが割り当てられ、現状 17 個のようです。
また、エラー時の一般的なユースケースが公式ドキュメントに詳しく記載されています。 また、エラー時の一般的なユースケースが公式ドキュメントに詳しく記載されています。 エラーパターンとしてStandard error model と Richer error modelの2つがあるようです。
プロトコルバッファを使っている場合は、Google が利用しているエラーモデルの利用を検討するように、とあります。
Generated at Client or Server の項目に見られるように、サーバー側がステータスコードを返すのは HTTP と同じかと思いますが、クライアント側でもステータスコードを生成して扱えるようです。
例えば、gRPC 呼び出しを行ったときにクライアント内部でエラーが発生した場合などがこういうケースに当たるんじゃないかと思います。
HTTP/2 で gRPC を利用した場合の各ステータスコード
HTTP/2 で gRPC 通信を行った際、ヘッダーには HTTPのステータスコード(Status)と、 gRPC のステータスコード(grpc-status)が含まれることになります。
Header: :status: 200 OK
Name Length: 7
Name: :status
Value Length: 3
Value: 200
:status: 200
[Unescaped: 200]
Representation: Indexed Header Field
Index: 8
:
:
:
Header: grpc-status: 0
Name Length: 11
Name: grpc-status
Value Length: 1
Value: 0
[Unescaped: 0]
Representation: Literal Header Field with Incremental Indexing - New Name
ただし、gRPC のステータスコードは何が返されることになっても HTTP のステータスコードは 200 が返るようになっているようです。
int grpc_status_to_http2_status(grpc_status_code /*status*/) { return 200; }
HTTP と gRPC のステータスコードのマッピング
gRPC サーバーからのレスポンスで、何らかで grpc-status を含まないレスポンスがあった場合、gRPCクライアント側で HTTP ステータスコードに応じたマッピングがされるようです。 gRPC サーバーではこのマッピングは使用しないようにと記載があります。
例えば、gRPC のステータスコードが空の場合でHTTPのステータスコードが 200 以外の場合は、httpのステータスコードに応じてマッピングがされるようです。これはおそらくクライアント側でエラーが発生した場合に該当するんじゃないかと思います。
if (grpc_status != nullptr || *status == 200) {
b->Remove(HttpStatusMetadata());
} else {
return absl::Status(
static_cast<absl::StatusCode>(
grpc_http2_status_to_grpc_status(*status)),
absl::StrCat("Received http2 header with status: ", *status));
}
}
まとめ
gRPC のステータスコードについザッとドキュメントをかいつまんで見た内容のメモでした。 HTTP と同じ感覚でいると監視周りなどで意図しない形になりそうなので、よく理解していきたいと思いました。