エンジニア的なネタを毎週書くブログ

東京でWebサービスの開発をしています 【英語版やってみました】http://taichiw-e.hatenablog.com/

バグチケットに各APIのリクエストとレスポンスが貼ってあったらバグの調査は早く終わるのか?

モヤモヤと考えたことを書き出しています。結論ありません。実践もまだしてません。

背景

私は今、こんな感じでInternalなWeb APIが相互作用するサービス*1に関わっています。
f:id:taichiw:20190107184003p:plain

また、こんな感じで組織が別れています*2
f:id:taichiw:20190107184619p:plain

さて、このサービスについて不具合が起票されることがあります。
リリース前のQAだったり、残念ながらリリース後、本番可動しているサービスに対してだったりします。
いずれにしても大事なこととして、不具合はここの視点、最も浅いレイヤである、UIの「挙動が期待通りでない」事象として発見されます。
f:id:taichiw:20190107185147p:plain

一方システム的には、不具合の原因は以下のいずれかになります(複数の組み合わせの場合もある)

  • UI componentにバグが有る
  • API 1にバグが有る
  • API 2にバグが有る
  • API 3にバグが有る
  • API 4にバグが有る
  • DB1のデータが正しくない
  • DB2のデータが正しくない

不具合を修正するためには、この中のどこに問題があるかを見つける必要があります。

どうすれば早く原因が見つかるのか

シンプルに、いずれか一つのプログラム(=UI component または API 1~4 のいずれか)にバグが有るケースを考えます。
バグが有る、ということは外から見たプログラムの挙動として、以下の2つのいずれかに分類することができます。

  • 正しいリクエストを受けているのに、レスポンスが正しくない
  • 正しいリクエストを受けているのに、次のAPIの呼び出しが正しくない あるいは データの更新が正しくない

たとえばAPI 3がバグっていて、「正しいリクエストを受けているのに、レスポンスが正しくない」場合
f:id:taichiw:20190107190453p:plain
API 3が正しくないレスポンスを返すので、それがAPI 1→UI と伝搬することになります。
この場合、API 3を修正する必要があります。

また、API 2がバグっていて、「正しいリクエストを受けているのに、次のAPIの呼び出しが正しくない」場合
f:id:taichiw:20190107191303p:plain
API 4そのものは正しく動作していますが、リクエストが誤っているため期待通りでないレスポンスを返し、最終的にそのレスポンスが原因となってUIの挙動が期待通りになりません。
この場合、API 2を修正する必要があります。

「赤い矢印」が見つかればどのプログラムがバグっているのかわかる

前項で見たとおり、期待通りでないリクエスト、またはレスポンスである、「赤い矢印」
f:id:taichiw:20190107191317p:plain
がどこから始まっているかがわかれば、バグのあるプログラムである、「赤い四角」
f:id:taichiw:20190107191417p:plain
の箇所が特定できそうです。

ということで、バグが起票された際に、全APIのリクエストとレスポンスがチケットに貼ってあれば、即座にどのAPIがバグっているのかわかるのでは? と考えました。
こんな表を自動生成することはできないでしょうか。

API リクエス レスポンス APIへのリクエス
API 1 f:id:taichiw:20190107191851p:plain f:id:taichiw:20190107191902p:plain to API 2 f:id:taichiw:20190107191929p:plain, to API 3 f:id:taichiw:20190107191851p:plain
API 2 f:id:taichiw:20190107191929p:plain f:id:taichiw:20190107192044p:plain to API 4 f:id:taichiw:20190107191317p:plain
API 3 f:id:taichiw:20190107191851p:plain f:id:taichiw:20190107192118p:plain
API 4 f:id:taichiw:20190107191317p:plain f:id:taichiw:20190107191902p:plain

※矢印はイメージです。実際はこの表の各セルに具体的なJsonが書かれます

Spring Cloud Sleuth でTraceIDを発行しているため、一つのUIアクセスから始まる各APIのリクエスト/レスポンスを集めてくるのは技術的には可能そうです。

「赤か青か」を判断するのが実は難しい?

上の表では、API 2は正しいリクエストを受けているにもかかわらず、API 2からAPI 4へのリクエストが間違っています。ここから、API 2にバグが有る、と推測することが可能です。
f:id:taichiw:20190107193039p:plain
では、API 2→API 4のリクエストが間違っている と気づくことができるのは誰でしょうか…。API 2はTeam C、API 4はTeam Dが担当しているので、それぞれのチームのエンジニアに気づくチャンスがありそうです。

API 2の担当エンジニアは気づけるか?

まず、API 2の担当エンジニアは、上の表から以下のことに比較的簡単に気づけそうです。

  • API 2のレスポンスが期待通りでない
  • API 4からのレスポンスが期待通りでない

ここから、API 4へのリクエストが間違っているか、API 4そのものにバグが有る という推測は立てられそうです。
しかし、API 4へのリクエストの検証についてはどうでしょうか。
シンプルな間違え*3ならばすぐ気がつけそうですが、もう少し複雑な間違えですとすぐには気づけないかもしれません。
また、API 2の担当エンジニアが、API 4のリクエスト使用を誤って理解しているかもしれません。

API 4の担当エンジニアは気づけるか?

API 2→API 4のリクエストが間違っている」ということにAPI 4の担当エンジニアが気づくためには、以下のことを理解している必要があります。

なぜならば、バグの起票時点では、UIレベルの情報しかないからです。
f:id:taichiw:20190107193948p:plain
これも、即座に正しいか誤っているか判断できる場合もあると思います。しかし、API 4の使われ方によっては、中間のAPIの仕様を知らないとリクエストの正誤の判断が難しいかもしれません。

リクエストの正しさの確認は狭間に落ちる?

…ということを想像していくと、API 2→API 4のリクエストの正しさの確認というのは、どちらのエンジニアにとっても難しいのでは…? という気がしてきました。

レスポンスの正しさの確認のほうが簡単かも

では一旦、「すべてのAPIのリクエストは正しい」と仮定して、レスポンスの正しさだけに注目したらどうでしょうか。

バグの起票時に、UIレベルで「本来Aという振る舞いをすべきところ、Bという振る舞いをしている」ということは記載されています。
この場合、「『B』の原因となるレスポンスを自分のAPIが返している」かどうかの確認は、リクエストの確認の正しさに比べると比較的難易度が低い …気がします。 自分の経験的には。

APIのレスポンスだけとりあえず並べてみる

レスポンスの正誤の判別は比較的簡単… という前提で、「バグ起票時に各APIのレスポンスが自動的に貼り付けられるツール」のようなものを想像してみます。

API レスポンス
API 1 f:id:taichiw:20190107191902p:plain
API 2 f:id:taichiw:20190107192044p:plain
API 3 f:id:taichiw:20190107192118p:plain
API 4 f:id:taichiw:20190107191902p:plain

※繰り返しになりますが、矢印のところには具体的なJSONが入るイメージです

システム構成が頭に入っていれば、以下のような図が見えるわけです。
f:id:taichiw:20190107195535p:plain
※データがおかしい可能性もありますが、今は除外して考えます

API 3には絶対バグがないことがわかった!バンザイ! といいたいところなのですが、
UI, API 1, API 2, API 4 のどれもバグ持ちの可能性が消えていません。
これだけでは、あまり何かが解決しているようには思えません。

いろいろ考えてみたけどこれだったら結局…

先程問題にあげた、「リクエストの正誤の方法」について掘り下げたほうが何か効果があるかもしれません。

今日はここまでです。

続きます…(多分)

*1:図は簡略化しています。現物はもっと大きいです。また、いわゆるマイクロサービスアーキテクチャに近いとは思いますが微妙に違う気もします。組織とか。

*2:この組織構成が良いのかどうかの話は、ここではしません。

*3:例えば、API 1 -> API 2 では Item A がリクエストされているのに、API 2 -> API 4 ではItem Bがリクエストされている というケースです。