gRPC Application のエラー設計
Web アプリケーションで error code, error message を返したくなる時があるはずです。HTTP JSON API とかでたまに見るのは status code が 200 なのに error が返ってくるものです。gRPC ではどうすれば良いのでしょうか。基本をおさらいしつつ浅く考えてみます。
Status Code
成功すると response と status code OK
が返ってきます。
何かしらのエラーが発生すると OK
以外のエラー status code が返ってきます。statuscodes.md にも記載されてますが、これらのコードは必ずしも server から返るわけではなく、client 自身が返す場合もあります。
基本的には gRPC アプリケーションで発生したエラーによって status code を変更するような設計にするかと思います。しかし、時には gRPC server (low level) で発生したエラーとアプリケーションのロジックで発生したエラーを分けたい & client にそのエラーの詳細を伝えたいといった事があるかと思います。そのような時は Richer error model を採用しましょう。
Error Details
Google では開発に使用しているエラーモデルが存在します。このモデルに記述されている details
がどんなエラーが発生していたのかを詳しく表現できるようなフィールドになってます。Google では一般的なエラーのニーズ(リトライ情報、不正なパラメータの情報など)をカバーできるように proto が定義されてます。これらのような proto を details
のフィールドへ格納することで表現することができます。
gRPC ではこのモデルに沿ってエラーを返せるようになってます。エラー詳細は response に付属される metadata 内に details
というキーに対して格納されて返ってきます。
- エラーコード
- status code
- エラーメッセージ (ライブラリの実装に依存するとのこと)
- Go や Nodejs では error として手に入る
- Go (server) -> PHP (client) だと details に string として含まれて手に入る
- 例:
{"metadata":{},"code":5,"details":"sql: no rows in result set"}
- 例:
- エラー詳細: gRPC の response に付属される metadata に
details
というキーに対して格納されて返ってくる
もちろん Google が定義した proto メッセージではなく、自前で proto を定義するのもありでしょう。
まとめ
- gRPC では
OK
以外はエラーとして扱うことを推奨されてる - エラー詳細は response の metadata を使う。details というキーに対して格納していく。
お試し
gRPC の server, client の挙動の確認ができる testing-grpc というものを作りました。このプロジェクトは grpc/grpc-go を使って開発されてますが、他の言語で(例えば PHP)実装された gRPC server, client にも同様の知識を応用できるのではないかと考えてます。
(もし宜しければ github star をお待ちしてます)