Contents
API設計の基本原則
公開するAPIであっても、非公開のAPIであっても、設計時に考慮すべき原則は同じです。非公開API(業務システムなど)では、厳しく適用する必要はありませんが、開発者のキャリア上、適切なAPI設計ができるようになることは意味があります。
なぜ適切にAPIを設計する必要があるか?
- 使いやすくするため…使いくいAPIは、最悪の場合、使われないこともあります。
- 変更しやすくするため
- 頑強にするため…セキュリティ問題に適切に対策がされている必要があります。
- 恥ずかしくないようにするため…一般公開しない場合でも、顧客に納品するシステムの一部として、開発レベルが疑われない水準である必要があります。
エンドポイント・URIの設計の原則
ユーザーにとって覚えやすく、どんな機能を持つAPIなのかがひと目でわかるのが良いURI(パス)です。
具体的には、下記の点を考慮して検討します。
- 短く入力しやすいURI
- 人間が読んで理解できるURI
- 大文字小文字が混在していないURI → 小文字に統一する。
- 改造しやすい(Hackableな)URI
- サーバ側のアーキテクチャが反映されていないURI
- ルールが統一されたURI
下記の点に注意してください。
- 複数形の名詞を利用する
- OK /books/123
- NG /book/123
- 利用する単語に気をつける
- スペースやエンコード(%)を必要とする文字を使わない
- 単語をつなげる必要がある場合はハイフンを利用する
- 単語をつなげる時は3語以下にする → それ以上増えると読みにくい
クエリパラメータかパスパラメータか
特にGETメソッドのときに、パラメータをクエリパラメータ(books?id=123)にするか、パスパラメータ(/books/123)にするか迷うと思います。
そのときは、下記の基準で決めていきます。
- 一意なリソースを表すのに必要な情報かどうか
- 省略可能かどうか
books?id=123のようなID項目は、リソースを一意にするために必要な情報なので、ここではパスパラメータを選択するのがベターです。
検索条件の項目のように、必須ではない項目は、クエリパラメータにしていきましょう。
URIのドメイン部分はどうするべきか
サブドメイン部分を指定できる場合は、https://api.springhack.com/のようにするのがベターです。多くの公開APIでそうされています。
サブドメイン部分を指定できない場合は、https://springhack.com/api/xxx のようにしていきます。
レスポンスデータの設計原則
レスポンスでの形式はJSONにする。JavaScriptと相性がよく、データサイズが小さくなるから。必要な場合のみ、JSON以外(XML等)を使用する。
レスポンスは少回数で必要なデータが取得できるようにAPIを設計する。
IDのリストだけ、IDのリストをループして詳細を取得するのはNG。1回で済むようにIDと付随する詳細情報も取得できるようAPIを設計するのが良い。
レスポンスデータはサイズが小さくなるように設計する。少回数でデータを取得できるようにすると、1APIのレスポンスが大きくなることがある。その場合は、クエリパラメータでレスポンスの必要項目を指定できるようにする等工夫すると良い。
不要な入れ子を作らないようにする。
{
"id": 123,
}
{
"data": {
"id": 123,
}
}
レスポンス項目のキーはキャメルケースを使用する。JavaScriptの命名規約において、キャメルケースの利用がルールつけされているケースが多いため。
{
"siteName": 123,
}
{
"site-name": 123,
"site_title": 123,
}
数値やコード値、種類・種別、区分は意味も項目に含めると良い。レスポンスを見ただけで意味がわかるとユーザビリティが上がります。コード値だけ返すAPIは、コード変換表や定義書をことあるごとに確認するはめになります。
{
"gender": 0,
"genderName”: "女性",
}
{
"gender": 0,
// 0って男性?女性?
}
レスポンスのステータスコードの原則
業務アプリケーションで使用するのは下記の番手です。
No | ステータスコード | 意味 |
1 | 200番台 | 成功 |
2 | 400番台 | クライアントサイドに起因エラー |
3 | 500番台 | サーバサイドに起因するエラー |
まず知っておきたいことは、X00番(400や500)はその番台を代表する基本コードであり、403や409などに振り分けを迷った場合は、400番に割り当てて良いということです。
特に使い分けが必要なのは400番台です。業務用のWebアプリケーションでは多くの場合このようにすると良いです。
- ログイン時ユーザ名・パスワード誤り → 401(Unauthorized)
- 権限チェックエラー → 403(Forbidden)
- 単項目チェックエラー → 400(BadRequest)
- 相関チェックエラー → 400(BadRequest)
- 登録時のID重複エラー → 409(Conflict)
- 排他チェックエラー → 409(Conflict)
基本的には、400番以外の適用を考え、それ以外は400番で返すようにします。迷ったら、400番に倒すという方針で問題ありません。
多くの開発現場では400番台は1種類か2種類しか使っていないようです。一般公開するAPIでなければ、あまり細かく出し分けるメリットがないからです。
私は次の3種類がクライアント側で判別できれば十分と思います。
- クライアントをログイン画面に遷移させるべきエラー
- クライアントが画面を再描画することで、操作を継続できるエラー
- クライアントが画面を再描画せずとも、入力値を変更することで操作を継続できるエラー
また、成功時は200番台のレスポンスコードを使うが、すべて200番にすることは一般的なので問題ありません。
エラー発生時のレスポンス内容
次の3つを含めるのがユーザビリティが高いです。
- 発生したエラーをすべて含める。
- 各エラーについて、どんな問題が起きたのかがわかる。
- 各エラーについて、どうすれば解決できるのかがわかる。
その他の知っておきたい原則
- APIは、APIの利用者に対するインターフェースにすぎず、内部の実装を抽象化したものにすぎない。→利用者(一般の人やクライアントサイド)にバックエンドの詳細がわかるようなAPI設計は良くない。
- URI(パス)は各階層の意味が同じになるように配慮する。→利用者が扱いやすく感じる。
- レスポンスボディの構造は、含まれるプロパティの数と深さが小さいほど良い。プロパティの数は20、深さは3層までが理解しやすい目安である。
API設計の手順(3ステップ)
STEP1.APIのユーザー、クライアントサイドのゴールを書き出す
APIのユーザーが、APIを使って達成したいゴールを書き出します。
ゴールは「ユーザーが何をできるか?」に対する答えになります。
プロバイダ=バックエンド側の視点ではなく、ユーザー側の視点でゴールを考えることがとても重要です。
「何をできるか?」を「どのようにできるか?」に分解していくと、それぞれのステップが各APIのゴールになります。「何をできるか?」を最初に大まかに定義して、「どのようにできるか?」に分解して書き出していきます。
STEP2.ゴールをリソースに対するアクションで表現する
STEP1で書き出した各APIのゴールを、「リソース(名詞)」に対する「アクション(動詞)」の形式で書いていきます。
STEP3.リソースをパスで、アクションをHTTPメソッドで表す
HTTPメソッドで表すのが難しい場合
実案件では、単なるCRUDでは表現できないアクションも良く出てきます。その場合は、下記のどちらかで対応します。
- POSTに寄せてしまう。
- アクションリソースにする。
1つ目はPOSTに寄せてしまう方法です。プロジェクト全体として、適当なHTTPメソッドに当てはめられない場合はPOSTを使用すると決めてしまいます。それで問題ありません。
多くの現場で実際に使われるのは、2つ目のアクションリソースにする方法です。アクションリソースと言っても、HTTPメソッドに当てはめられないアクション(動詞)を英字にしてパスに含めるだけです。こちらの方法を取るときも、POSTを使うようにします。
参考書籍
本ページを書くにあたって、自習のために読んだ本を紹介します。
- Web API: The Good Parts(おススメ度★★★★★)
- API設計の原則が簡潔にまとめられている。薄くて読みやすい。
- Web APIの設計(おススメ度★★★)
- API設計の手順や実際に迷うことへの対応も書かれている実践的な本。分厚いため、The Good Partsを先に読むと良い。