ProtobufでのgRPCエラーハンドリングパターン

堅牢なgRPCエラーハンドリングのためのprotobufスキーマ設計。ステータスコード、エラー詳細、構造化エラーレスポンス、google.rpc.Statusパターンを解説します。

Services & RPCs

詳細な説明

gRPCサービスのエラー構造化

gRPCはトランスポートレベルのエラーに数値ステータスコードを使用しますが、アプリケーションレベルのエラーにはより豊富な情報が必要です。構造化されたエラー詳細を運ぶprotobufスキーマの設計は、本番サービスのベストプラクティスです。

syntax = "proto3";

package api.v1;

import "google/protobuf/any.proto";

service OrderService {
  rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse);
  rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse);
}

message PlaceOrderRequest {
  string customer_id = 1;
  repeated OrderItem items = 2;
  PaymentInfo payment = 3;
}

message PlaceOrderResponse {
  oneof result {
    Order order = 1;
    OrderError error = 2;
  }
}

message OrderError {
  ErrorCode code = 1;
  string message = 2;
  repeated FieldViolation field_violations = 3;
  map<string, string> metadata = 4;
}

enum ErrorCode {
  ERROR_CODE_UNSPECIFIED = 0;
  ERROR_CODE_INVALID_INPUT = 1;
  ERROR_CODE_OUT_OF_STOCK = 2;
  ERROR_CODE_PAYMENT_DECLINED = 3;
  ERROR_CODE_CUSTOMER_NOT_FOUND = 4;
  ERROR_CODE_RATE_LIMITED = 5;
}

message FieldViolation {
  string field = 1;
  string description = 2;
}

message OrderItem {
  string product_id = 1;
  int32 quantity = 2;
}

message PaymentInfo {
  string method = 1;
  string token = 2;
}

message Order {
  string order_id = 1;
  string status = 2;
  double total = 3;
}

message CancelOrderRequest {
  string order_id = 1;
  string reason = 2;
}

message CancelOrderResponse {
  bool success = 1;
}

エラーハンドリング戦略

戦略1: レスポンス内のoneof(上記) — レスポンスに成功ペイロードまたはエラーオブジェクトのいずれかを含めます。クライアントはどのバリアントが設定されているかを確認します。エラー詳細をインバンドかつ型付きに保ちます。

戦略2: 詳細付きgRPCステータス — gRPCエラーステータスを返し、google.rpc.Statusgoogle.protobuf.Anyを使用して構造化された詳細メッセージを添付します。Googleのエラーモデルに従います。

戦略3: レスポンス内のエラーフィールド — 通常のレスポンスと並んでオプションのエラーフィールドを含めます。エラーフィールドの存在が失敗を示します。

ベストプラクティス

  • ドメイン固有のエラーコードをenumとして定義
  • プログラマティックハンドリング用の機械可読エラーコードを含める
  • ロギングとデバッグ用の人間可読メッセージを含める
  • バリデーションエラーにはFieldViolationを使用して、どのフィールドが無効かを正確に特定
  • サービスと並行してエラー型をバージョニングし互換性を維持

ユースケース

入力バリデーション失敗、ビジネスルール違反、マイクロサービス間の運用エラーに対する構造化された解析可能なエラーレスポンスが必要な本番gRPC APIの設計。

試してみる — Protobuf Definition Parser

フルツールを開く