エンドポイントの設計
設計の注意点
- 短くて入力しやすいこと
→ 極力、不要な文字や重複は省くこと。 - 可読性を考慮する
→ 単語の省略はしないこと。 - 小文字に統一し、文字間はハイフネーションで繋ぐ
→ キャメルケースやスネークケースは非推奨。 - ルールを統一すること
→ 複数のAPI間で似たような情報の取得に際して予測可能な設計にしておくこと。 - 内部のアーキテクチャに依存しないこと
→ 脆弱性を突かれる危険がある。 - バージョン番号をつけること。
→ 今後の拡張性のため。 - 名詞で構成し、動詞を含めないこと(ただし、searchは検索のみを目的にしたAPIであることを明示する意味で置くことがある)
1. `service`や`api`といった文字が不必要。
http://api.example.com/service/api/users/
2. `ms`や`u`が何を示すのかわからない。(実際職場でありました。センスを疑う。)
http://api.example.com/ms/u/
3. キャメルケースやスネークケースは推奨されない。
http://api.example.com/userId/
4. クエリパラメータ指定なものとURI指定のものが混在する。
http://api.example.com/userId/id?=100
http://api.example.com/userId/100/name
5. 内部でCGIやPHPを利用していることがわかり、脆弱性が発見された場合の攻撃対象となりやすい。
http://api.example.com/cgi-bin/getIofo.php?id=100
HTTPメソッドを用いてエンドポイントを増やさずに機能を増やす。
主なメソッド | 役割 |
---|---|
GET | リソースの取得 |
POST | リソースの新規登録 |
PUT | リソースの更新 |
PATCH | リソースの一部更新 |
DELETE | リソースの削除 |
POST
は初回登録のみで、それ以降はPUT
かPATCH
を利用するのが正しい。後者2つの使い分けは、リソースが膨大で一部のみ更新したい時にPATCH
を使う。
これらのメソッドを使い分けることで、エンドポイントを増やすことなく提供できる機能を拡張できる。
例
http://api.example.com/v1/users
+ GET
→ ユーザ一覧取得
http://api.example.com/v1/users
+ POST
→ ユーザ新規登録
クエリパラメータの設計
取得数をクエリパラメータで指定する方法
膨大なデータから一部を取得する場合に位置を指定する方法は相対位置と絶対位置の2パターンある。
相対位置指定
per_page=50&page=3
limit=50&offset=100
前者の方法では、1ページあたりの件数を指定してその何ページ目(page=1からカウント)の情報を取得するかを指定している。
後者の方法では、offsetの何番目(offset=0からカウント)からカウントして何件取得するか(limit)を指定している。
ただしこの方法は遅いかつ、探索中に更新されると情報に齟齬が生まれる。
絶対位置指定
→データのIDや時刻を記録しておき、あるIDより前
やある時刻以降
といった指定をする方法。
クエリパラメータで指定させるかパス内に指定させるか
- 一意なリソースを示すものか:アクセストークンなどはリソースとは直接関係ない。
- 省略可能か:パスに埋めると省略できなくなる。
レスポンスデータの設計
まずデータフォーマットを決める。
→ 時代の流れはJSON。 XML?知らない。
設計の注意点
1 エンベロープは冗長なのでいらない。
{
"header":{
"status": "success",
"errorCode": 0
},
"responce":{
"key1": "value1"
"key2": "value2"
},
}
ヘッダーのメタデータも含めて全てのデータを包む構造をエンベロープという。HTTPヘッダに入れればいい。
2 データはなるべくフラットにすることが推奨される。(関連性のあるデータ動詞は階層構造にする。ケースバイケース)
3 配列をそのまま返すのはセキュリティ上危険(JSONインジェクション)。オブジェクトにして包むこと。
エラー時の返値設計
- ステータスコードでエラーを表現すること。
- 200返しておきながらエラーとかしない。
- レスポンスボディにはエラー時の専用のデータ構造を用意し、そこにエラー情報を格納する。