0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

protobuf.devのAPI Best Practicesを読んでいく全部俺Advent Calendar 2024

Day 19

API Best Practices ~ステータスコードの伝播は慎重に

Posted at

ステータスコードの伝播は慎重に

RPCサービスはエラーを調査し、呼び出し元に意味のあるステータスコードを返すことに注意する必要があります。

例として、引数を取らないProductService.GetProductsを呼び出すクライアントを考えてみましょう。

digraph toy_example {
  node [style=filled]
  client [label="Client"];
  product [label="ProductService"];
  locale [label="LocaleService"];
  client -> product [label="GetProducts"]
  product -> locale [label="LocaliseNutritionFacts"]
}

GetProductsの一部として、ProductServiceはすべての製品を取得し、各製品に対してLocaleService.LocaliseNutritionFactsを呼び出すかもしれません。
ProductServiceが誤って実装されている場合、LocaleServiceに間違った引数を渡して、INVALID_ARGUMENTが発生する可能性。
ProductServiceがエラーを呼び出し元に不注意に返すと、クライアントはINVALID_ARGUMENTを受け取ります。
なぜなら、ステータスコードはRPC境界を越えて伝播するからです。
しかし、クライアントはProductService.GetProductsに引数を渡していません。
そのためエラーは無意味なものよりも悪いものです。非常に混乱を招くでしょう。

代わりに、ProductServiceはRPC境界で受信したエラーを調査する必要があります。
つまり、実装するProductService RPCハンドラです。
呼び出し元から無効な引数を取得した場合、INVALID_ARGUMENTを返す必要があります。
下流の何かが無効な引数を受け取った場合、INVALID_ARGUMENTをINTERNALに変換してから呼び出し元にエラーを返す必要があります。

ステータスエラーを不注意に伝播すると、混乱につながります。
さらに悪いことに、すべてのサービスがクライアントエラーを転送しアラートが発生しないため、見えない障害につながる可能性があります。

一般的なルールは、RPC境界ではエラーを調査し、適切なステータスコードで呼び出し元に意味のあるステータスエラーを返すことです。
意味を伝えるために各RPCメソッドは、どのような状況でどのようなエラーコードを返すかを文書化する必要があります。
各メソッドの実装は、文書化されたAPI契約に準拠する必要があります。


ステータスコードの一覧はこちら
https://grpc.io/docs/guides/status-codes/

よく遭遇するケースとしては、複数のサブRPCをコールするもので UNAVAILABLE エラーが返ってくるなど。
サブRPCの UNAVAILABLE なのか、自身のサービスが UNAVAILABLE なのかを区別するためには、ステータスコードを適切に変換する必要があります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?