🐍

API レスポンスデータの設計

2023/09/10に公開

はじめに

https://www.oreilly.co.jp/books/9784873116860/
「Web API:The Good Parts」を読んだ際のメモ。
主に 3 章の内容になります。

データフォーマット

JSON にデフォルトとして対応し需要や必要があれば XML に対応する
XML に対応していた API もアップデート時に JSON のみに切り替わるような API もあるようなので、JSON のみサポートしていれば基本的には大丈夫そう。
それ以外の形式としては PHPserialize など

フォーマットの指定方法にはクエリパラメーターを使う方法が最もよく使われている

https://api.example.com/v1/users?format=json

それ以外の方法としては HTTP ヘッダに含める方法や拡張子を使う方法がある。

データの内部構造

API のアクセス回数がなるべく減るように設計する
友人一覧を取得する API として UserId だけを返す仕様だと、一覧を取得したのちに再度ユーザー情報を取得しなければならない。
→ アプリケーションの特性を踏まえた上で利用者が使いやすい構造に設計する

エンベロープは冗長なため避けた方が良い
下記のようにメタ情報をレスポンスと分けて入れるような構造は避けるべき。
必要なメタ情報は HTTP ヘッダを利用する。

{
	"header": {
		"status": "success",
		"errorCode": "0"
	},
	"response": {
		データ
	}
}

構造はなるべくフラットにすべき。ただし階層化した方が良い場合は階層化する。
とても曖昧な表現だけど、場合によるという感じ。

配列を返す場合もオブジェクトでラップする
JSON は配列とオブジェクトのどちらでもトップレベルに配置できるが、以下のような理由からオブジェクトでラップする方がおすすめ。

  • レスポンスデータの構造の統一のため
  • セキュリティ上のリスクを避けるため(JSON インジェクション)

ページネーションが必要な場合は続きがあるという情報を含める

{
	"timelines": [
		データ
	],
	"hasNext": ture
}

取得するデータば全体で何件あるかという処理は重くなりがち。
全体の件数が重要でなければ上記の実装でおこなうと無駄が少ない。

各データのフォーマット

データ名は一般的な単語を使い、API 全体を通して統一する
書籍では、適切な名前を検討するのに ProgrammableWeb で既存 API を調べる方法をおすすめしているが 2022 年に閉鎖されてしまったらしい。
今だととりあえず ChatGPT に聞いておくとベターかも。

日付のフォーマットは RFC3339 を使うのがベター

2015-10-12T11:30:22+09:00

巨大な数値の場合は文字列として扱う
JavaScript の数値型は 64bit 浮動小数として扱われる。(全ての数値が double として扱われる)
53bit より大きい数値は誤差がでてしまうことを理解しておく必要がある。

エラーの表現

適切なステータスコードを利用する
そのまま

エラーの詳細はレスポンスボディに含める
ヘッダに含めることもできるが一般的なのはボディに含める方法

エラー情報には詳細コードと詳細情報へのリンクを最低限含める
ユーザー向けと開発者向け両方のメッセージを含める方法もある。

意図的に不正確な情報を返す場合もある
たとえばブロックされているユーザー情報を取得しようとした際に、認可エラー(403)を返すのではなく、そもそも存在しないものとして 404 エラーを返すといったこともある。

さいごに

最後まで読んでいただき、ありがとうございました。

Discussion