はじめに
今後のAPIエンドポイント設計時に見返せるよう、サマリを残しておく。
※この記事は、O'Reilly『WebAPI The Good Parts』の2章「エンドポイントの設計とリクエストの形式」の内容のサマリとなっています。
エンドポイント設計の重要な原則
APIにおけるエンドポイントの設計=URIの設計であるため、良いURIの設計が求められる。
本書において重要な原則は、以下であると述べられている。
覚えやすく、どんな機能を持つURIなのかがひと目でわかる
より掘り下げて具体的にすると、以下のようなURIが望ましいとされている。
- 短く入力しやすいURI
- 人間が読んで理解できるURI
- 大文字小文字が混在していないURI
- 改造しやすい(Hackableな)URI
- サーバ側のアーキテクチャが反映されていないURI
- ルールが統一されたURI
それぞれのURIについて、具体例を用いながら紹介する。
短く入力しやすいURI
読んで字の如く。シンプルで、覚えやすいことが重要である。
例えば以下のようなURIがあるとする。
http://api.example.com/service/api/search
何らかの検索用のAPIであることは分かるが、「api」というワードがホスト名と重複していること、「service」という概念のワードが含まれていることからやや冗長な印象を受ける。以下のように短くしてしても、URIに含まれている情報はほぼ変わらない。
http://api.example.com/search
同じ内容を表すのであれば、短くシンプルな方が理解しやすく、覚えやすく、入力間違いも減るため、好ましいと言える。
人間が読んで理解できるURI
上記「短く入力しやすいURI」の例で出てきた検索APIのように、URIを見れば何を目的としたAPIなのか分かることが望ましい。
例えば以下のような意味不明のURIがあったらどうだろうか。
http://api.example.com/sv/u
「api」とあるためAPIであることは分かるものの、「sv」、「u」の意味が分からない。「sv」は「server」や「service」かもしれないし、「u」は「user」の略かもしれない。こうした、設計者しか分からないようなむやみな省略形を使わないことは意識しておくべきポイントである。
また、理解しやすいURIにするための2つ目のポイントとして、APIでよく利用されている英単語を利用することが挙げられている。
例えばECサイトで製品情報を取得するためのAPIを考えてみる。
http://api.example.com/products/12345
http://api.example.com/productos/12345
http://api.example.com/seihin/12345
1番目は英語、2番目はスペイン語、3番目は日本語が入っている。
スペイン語のケースは英語と似ているためタイポかもしれないという疑惑を生じさせるし、日本語のケースは日本語を理解できない人には伝わらない。いうまでもなく、1番目のケースが分かりやすいといえる。
一般的にAPIで使われる単語を知るには、実際のAPIを見てみるのが一番として、本書ではProgrammable WebのAPIドキュメントを参考にすることが推奨されている。また、1つのAPIだけでなく、複数のAPIを見比べて、最も使われていてかつしっくりくる単語を選ぶべきと紹介されている。
大文字小文字が混在していないURI
こちらは文字通りで、以下のようにアルファベットの大文字と小文字を混在させず、基本的に全て小文字を使うということを意味している。
http://api.example.com/Users/12345
http://example.com/API/getUserName
大文字と小文字の混在はAPIを分かりづらく、間違えやすくするため、どちらかに統一した方がよく、標準的に選択されているのは小文字である。
またここで、仮にクライアントから大文字を含むリクエストを受け付けた場合の挙動として、404 NotFoundを返却するケースが多くなっていることが紹介されている。
そもそもHTTPにおいてURIは「スキーマとホスト名を除いては大文字と小文字は区別される」と仕様に書かれており(RFC7230)、小文字で定義しているURIに大文字が含まれていた場合エラーになるのは当然であり、特に問題がないと著者は言及している。
改造しやすい(Hackableな)URI
ハックしやすいURIというのは、URIを修正して別のURIにするのが容易であることを意味する。例えば何らかのアイテムを取得するための以下のようなエンドポイントがあったとする。
http://api.example.com/v1/items/123456
このURIを見て直感的に分かるのは、このアイテムのIDが123456であるという点であろう。また、この番号を書き換えると、他のアイテムの情報にもアクセスができることが推測できる。
あるURIから他のURIを想像することが可能であれば、開発者がスムーズにAPIを扱うことができる。仮に開発者がAPIドキュメントを熟読していなかったとしても、それによって引き起こされるバグの問題も起こりづらくなることなどがメリットとして挙げられている。
サーバ側のアーキテクチャが反映されていないURI
ここでは先に例を挙げる。以下のようなURIがあったらどうだろうか。
http://api.example.com/cgi-bin/get_user.php?user=100
おそらく、このAPIがPHPで書かれていて、CGIとして動作しているのであろう、ということが分かってしまう。こうした情報はAPIの利用者的には全く必要がない上、サーバの脆弱性を突いて悪事を働こうとする人たちの格好の餌食になってしまう可能性もある。
こうしたことから、URIにはサーバ側のアーキテクチャやディレクトリ構造を反映する必要は全くない。
ルールが統一されたURI
複数のAPIが異なるルールで構築されていた場合を考えてみる。
#友達情報の取得API
http://api.example.com/friends?id=100
#メッセージの投稿API
http://api.example.com/friend/100/message
友達情報の取得APIではfriendsという複数形が使われている上、idをクエリパラメータで指定するようになっている。一方、メッセージの投稿APIでは単数形が使われており、idをURIのパスに入れる形になっている。
これらは明らかに統一感がなく、格好悪いだけでなくクライアントを実装する際に混乱を招きやすい。以下のようにルールを統一しておいた方が分かりやすいことは一目瞭然である。
#友達情報の取得API
http://api.example.com/friends/100
#メッセージの投稿API
http://api.example.com/friends/100/message
おわりに
私自身、これまでAPIのエンドポイントが分かりやすいと感じるかどうかは感覚的に判断していたが、本書で示された原則によってそれらが言語化され、明確になったと感じる。
本書はAPI設計時に抑えておくべきポイントが多く詰め込まれているため、設計時のチェックリスト的に読み直していきたい。