サービス間の例外ハンドリングについて議論したメモ


社内の議論で一般化できそうなのはqiitaに書いてみる。有用性は微妙・・

前提

クレジットカードを扱う、共通基盤的なマイクロサービス P (Provider) がある。

ユーザ向けのサービス C (Consumer) は、クレジットカード登録を利用している。筆者はこのサービスの開発を担当している。

C はクレジットカード登録や商品購入などのAPIをもっており、ユーザからリクエストを受け取ると、内部では C にクレジットカード登録や決済などのリクエストを送っている。

問題になったこと

クレジットカード登録時に、カード裏の番号 cvv を入力する必要がある。この番号は4桁以内である。

サービスCは、特にcvvの長さのバリデーションを行わず、そのままサービスPに送っていた。サービスPは400 Bad Requestを返しつつ、エラーのSlack通知をしていた。エラーが定常的に見られたため、Pの開発者は、Cの開発者にvalidationをかけてほしいと言った。

論点

サービスC側としては、cvvの長さのvalidationをかけることは可能だが、いくつかの疑問があった。

そもそもこの種のエラーは、引き起こさないべきなのか?
リクエストを送ってそのエラーのタイプをハンドリングするほうが実装が楽で、各サーバでのバリデーションはドメインロジックの分散を生むので、やりたくない場合もある。

また、今回でいうとPayment Gatewayに問い合わせないと最終的に正しいcvvかはわからないので、長さのvalidationだけを特別扱いする理由はあるのかどうか。
本当にSlack通知する必要があるタイプのエラーなのか?

という疑問をもとに、議論をした。

結論

以下の場合に限り、consumerに事前のバリデーションを強制させてよい、ということになった。

  • consumerがエンドユーザではなく内部のサービスである。
  • バリデーションロジックが簡潔である。
  • バリデーションロジックがstableである。(今後そう変わらない)

今回のケースでは、cvvは4桁以内という、簡単かつそう変わらないロジックである。

これにより、プロダクト全体として、バグ早期発見につなげることができる場合があるため。

その場合、providerはドキュメントを用意しconsumerにわかるようにする。

おまけ

Pチームのエンジニアが議論まとめてくれたので、そのまま貼る。

  • P Team should be responsible for keeping updated with any changes to the rules for credit card validations.

  • P should document the basic validation rules for CVV, Credit Card numbers, expiry dates.

  • P should inform its consumers when there are any validation changes.

  • Consumers should implement the validation rules. Ideally for the best User-Experience this should be client-side, but server-side is be good enough to prevent bad requests going to payment gateway.

  • P will generate Airbrake/ErrBit alerts when validation rules are broken. And P Team will identify the consumer and inform them of the problems.