APIの開発を行うなら一度は読んでおきたい書籍「Web API: The Good Parts」を先日読みました。
非常に参考になる情報がたくさんありましたので、気になった箇所を備忘も兼ねてまとめてみました。
特にはじめてAPIを独学で構築してみる方にとっては今回まとめた内容については気になるもしくは、気になっていた部分かと思います。
まさに自分がそうでしたが、エンドポイントの命名規則であったり、リクエスト形式、そしてレスポンス形式などどのように設計すれば良いか分かりませんでした。
この本を読むことで、APIを美しく書くポイントがわかるようになります。
エンドポイントの設計とリクエストの形式
エンドポイントの設計を行ううえで重要な考えは次のとおりです。
覚えやすく、どんな機能を持つURIなのかがひと目でわかるです。
どういうことかもう少し具体的な話に落とし込むと次の6つの要素を指しす。
1. 短く入力しやすいURI
短くて入力しやすいことは覚えやすい事につながります。
具体的なエンドポイント例を見ることでイメージがつき易いと思います。
http://api.example.com/api/v1/users/getAllUsersListWithDetailsIncludingRolesAndPermissions
この例だと、入力も面倒ですし、覚えるのも大変で、ユーザ体験がすごく悪いですね。
http://api.example.com/v1/users
どうでしょうか?改善後のエンドぽいとの方が短くて分かりやすいと感じませんか?
それに直感的にどういう動作をするのかがわかると思います。
2. 人間が読んで理解できるURI
APIを実際に動かすのはプログラムですが、そのプログラムを書くのは人間です。
なので、エンドポイントも人間が呼んで理解できる文字列になっているとGoodです。
本書に非常に良いエンドポイント例がありましたのでそちらを参考に説明します。
http://api.example.com/sv/u
↑のエンドポイントをぱっと見た時sv
とu
が何を意味しているのかわからないと思います。
推測で良いならsvはservice、uはuser(s)でしょうか?
このような極端な省略形は読み手に負担がかかるので、お勧めしません。
さらに、当たり前のことですが、スペルミスがないことも重要です。
3. 大文字小文字が混在していないURI
URIの中の文字列で大文字小文字の混在は非推奨で、全て小文字に統一すべきという話です。
大文字と小文字の混在は分かりづらく、間違えやすいからです。
ホスト名は通常小文字で表現されるため小文字に合わせると良いです。
また、getUserNameのようなキャメルケースの方がわかりやすいと言う意見もありますが、そもそもURI内にそのような名前の付け方に問題があるそうです。
4. 改造しやすい(Hackable な)URI
Hackableとは、URIを修正して別のURIにするのが容易という意味です。
容易に修正できるようにするにはURIの命名がシンプルであるべきです、つまり読み手にも易しくなります。
そうすると、APIのドキュメントを上か下まで見るストレスを軽減できるメリットもあります。
5. サーバ側のアーキテクチャが反映されていないURI
URI内に次のようなサーバ側のアーキテクチャの反映は不要です。
http://api.example.com/cgi-bin/get_user.php?user=100
APIを利用する側はそのAPIがどのような言語で書かれているかなど気にしません。
逆にこのようなケースを喜ぶ人はサーバの脆弱性を突くような悪意ある第3者です。
6. ルールが続されたURI
URIの構造で単数形や複数形、同じ意味の単語「findやsearch」などがバラバラに使われていると利用側で要らぬトラブルが発生します。
そのためルールは統一すべきです。
エンドポイント設計の注意点
複数形の名詞を利用する
本書では複数形で設計することを推奨しています。
単数形のエンドポイントも世の中にあるらしいのですが、理由としてはDBのテーブル名が複数形を表すのが適切と言われるのと同じ意味です。
ただ英単語の中には複数形にすることで単語の語尾が変わるものもあるので、英語に慣れていない人は辞書で調べるのがお勧めです。
利用する単語に気をつける
APIで検索する機能用のエンドポイントを考えたときに、英単語としては「find」や「search」を思い浮かべると思います。
意味的にどちらが適切かを判断するのは英語がネイティブでないと厳しいです。
その場合はProgrammableWebサイトであらゆるAPIの事例を見ることで自分と同じようなサービスを提供しているAPIを参考にすることが良いです。
※残念ながらProgrammableWeb閉鎖されていました。
スペースやエンコードを必要とする文字を使わない
パーセントエンコーディングを使わなければいけないような文字は使わないことです。
一番分かりやすい例で言うと、日本語です。
日本語を使うとパーセントエンコーディングされてエンドポイントの意味が分からなくなるからです。
単語を繋げる必要がある場合はハイフンを利用する
単語を繋ぎ合わせるケースとしてよくあるのが、
- ハイフンを使う
- アンダースコアを使う
- 次の単語の先頭を大文字にする
でしょうか。
結論として、好みで決めて良さそうです。
もちろんルールとして統一する必要はありますが。
レスポンスデータの設計
データフォーマット
議論の余地なくJSONで良いと思う。
需要や必要性があればXMLでもいいが、そういった制約がなければ基本はJSONで良い。
データの内部構造の考え方
APIのレスポンスデータでまず考えるべき点は、APIのアクセス回数をなるべく減らすようにすることです。
例えばユーザ情報を取得するAPIを叩いと際に、ユーザID一覧を返すAPIとユーザID+付属情報(プロフィール情報)を返すAPI、どちらがAPIの実行回数が少ないでしょう?後者の方が少ないと思います。
つまり、ユースケースを考えた時にAPIがどのような使われ方をするかが重要になります。
レスポンスの内容をユーザが選べるようにする
何度もAPIを呼び出すような設計は避けるべきです。
何度も呼び出さないで済むようにAPIのレスポンスには返せるだけのデータを返すことがシンプルです。
しかし、毎度全てのデータを返しているとデータ受信のレスポンスが悪くなります。
そこで解決の1つとして、必要なレスポンスの内容のみを返すようにすればいいのです。
クエリパラメータを使うことで、利用者側に必要なレスポンスを選択できるようにしましょう。
データはフラットにすべきか
JSON構造で全てのフィールドを同じ階層(つまりフラット)に置くか、階層構造にするかどちらが良いかという話。
どちらが良いかは状況によるそうです。
ただ、意味のない階層構造は避けるべきです。
例えば複数項目をまとめただけなどです。
階層構造にする意図が明確にあるなら、階層構造でも良いとのことです。
配列とフォーマット
レスポンスのフォーマットとして配列で返す方法と、レスポンス全体をオブジェクトで返す方法をがあります。
[
{
"id": 1111
"name": xxxx
"address": xxxx
},
{
"id": 2222
"name": xxxx
"address": xxxx
}
]
{
"friends": [
{
"id": 1111
"name": xxxx
"address": xxxx
},
{
"id": 2222
"name": xxxx
"address": xxxx
}
]
}
本書ではオブジェクトで返すことを推奨しています。
理由としては次の3つです。
- レスポンスデータが何をしているのかが分かりやすくなる
- レスポンスデータをオブジェクトに統一することができる
- セキュリティ上のリスクを避けることができる
レスポンスデータが何をしているのかが分かりやすくなる
friendsのキーが付いているので、id,name,addressガナを意味しているのかが分かりやすいです。
反対に配列で返すパターンだと、どのような意味のデータなのか推測が難しいです。
レスポンスデータをオブジェクトに統一することができる
レスポンスデータのオブジェクトを統一することで、ユーザ側がレスポンスオブジェクトを前処理する共通処理を書きやすくなります。
セキュリティ上のリスクを避けることができる
オブジェクトにすることでJSONインジェクションからの攻撃のリスクを避けることができます。
最後に
今回ご紹介した内容は本書のほんの一部です。
他にも、多く参考すべき内容が書かれています。
少しでも興味を持っていただけたなら是非書店で手に取ってみてはいかがでしょうか。