仕組みから学ぶ Web

API 設計

他人が使う契約をつくる

API は一度公開すると簡単には変えられない契約になる。リソースの切り方、同じリクエストが2回届いたときの振る舞い、失敗の伝え方。これらは実装の都合ではなく、呼ぶ側が安全なコードを書けるかどうかで決まる。

読み終わると、これに答えられるようになります

  • ?決済 API に同じリクエストが2回届いたらどうなるべきか
  • ?エラーレスポンスに何を入れると呼び出し側が自動復旧できるのか
  • ?GraphQL にすると何が楽になり、何が難しくなるのか
応用14

リソース設計 — 一度公開したら変えられない契約

URL は動詞ではなく名詞で切る、の理由。そして「きれいな REST」に収まらない操作をどう扱うか。

レスポンスの1フィールドを削除したら、把握していなかった3つのクライアントが壊れた

応用14

冪等性 — 同じリクエストが2回届く前提で設計する

ネットワークがある限り、再送は異常ではなく正常系。2回実行されても壊れない形をどう作るか。

決済 API のタイムアウト後にリトライし、同じ注文で2回課金された

応用13

エラー設計 — 呼び出し側が正しく振る舞える情報を返す

エラーは失敗の通知ではなく、次に何をすべきかの指示。リトライしてよいか、直せば通るかを伝える。

すべてのエラーを 200 + { success: false } で返し、クライアントが一時障害を延々とリトライした

発展15

REST と GraphQL — 何を楽にして、何を難しくするか

過不足のない取得という利点の裏で、キャッシュ・認可・負荷制御がクライアント任せから自分の責任に移る。

GraphQL 導入後、CDN キャッシュが一切効かなくなり、オリジンの負荷が10倍になった

応用14

ページネーション — 数えて飛ばすか、続きから取るか

offset は「ページ番号」という画面の都合から来ている。件数が増えると遅くなり、データが動くと境界がずれる。カーソル方式が何を解いて、何を捨てるのか。

offset で一覧を書き出すバッチが、毎回数件ずつ静かに取りこぼしていた