HerokuのAPIチームの一員、Wesley Beary氏がHTTP+JSON API作成のためのガイドラインを要約した形でまとめた。
これは一般的な推奨からはじまっている。
- API呼び出しはすべてTLSを使う必要がある。非TLSの呼び出しには
403 Forbidden
を返す。 - APIには必ずバージョンを付けること。バージョンの指定には
Accept
ヘッダを使う。デフォルトバージョンに頼る代わりに、クライアントはAPIバージョンを指定する必要がある。 - リソースのキャッシングをサポートするために、
ETag
ヘッダを使うこと。 X-Request-ID
の付いたレスポンスを識別すること。これはログやデバッグに役立つ。- 大きなレスポンスを扱うために、
Range、Content-Range、Next-Range
を使うこと。
リクエストについて、次のように述べている。
- 以下のような適切なステータスコードを返すこと。
200: 成功したGET
もしくは同期DELETE、PATCH
201: 成功した同期POST
…
401: 認証されていない呼び出し
429: 多すぎるリクエスト
など。 - 利用可能であれば、完全なリソースを返すこと。
- リクエストにおいて、JSONレスポンスと対称となる、シリアライズされたJSONを受け付けること。
- 一貫したパス形式を使うこと。シングルトンを参照していない限り、リソース名には複数形を使うべきだ。
- ホスト名と揃うよう、パスと属性には小文字を使うこと。
- アプリケーション名など一部リソースは、UUIDに加えて名前で指定できるようにすること。
- ルートパスの近く配置されるよう、リソースのネストの深さを制限しようとすること。
レスポンスに関して、Beary氏はこう提案する。
- 各リソースにはグローバルにユニークなIDを使うこと。
- リソースは標準的なタイムスタンプを提供すること。
- タイムスタンプにはISO8601形式のUTCを使うこと。
- レスポンスの構造を変えることなく関係するリソースの詳細を入れられるよう、外部キーリレーションをネストすること。
- 詳細なエラーを提供すること。これには、マシンが読めるID、人間が読めるエラーメッセージ、詳細情報を指すオプションのURLが含まれる。
- リクエストのレート制限を定めて、
RateLimit-Remaining
のようなヘッダを使って、利用可能なリクエストトークン数を、レスポンスごとにクライアントに通知すること。 - JSONはすべてのレスポンスで圧縮(minify)されるべきだ。
さらに、次のようなアドバイスも含まれている。
- マシンが読める形式で、JSONスキーマを提供すること。
- 開発者向けに詳細なAPIドキュメントを含めること。
- 開発者がAPIをテストできるようにすること。
- APIはその安定度合いにしたがって、マーク付け(prototype/development/production)されるべきだ。
私たちはBeary氏に、これらの指針をどうやって考え出したのか尋ね、その一部について説明してもらった。
InfoQ: あなたには最初から指針があったのですか?
WB: 一部は早くからありましたが、かなりラフなもので、私の頭の中にだけありました。私の考えには、github.com/fog/fogでの仕事と各種APIを使ってきた経験が、大いに役に立っています。
InfoQ: 最初から指針があったわけでないなら、あなたはどうやってAPIを開発していたのですか? 反復作業を通してですか?
WB: きちんとした指針というのはなくて、それは確かに反復プロセスでした。残念なことに、これは多少スピードが遅いのに加えて、スケールすることができませんでした。新しいものを加える上で障害になったのです。私たちは意思決定を展開する助けになるよう、この指針を作りました。引き続き反復作業によるところもありますが、たいていは指針にもあります。まだ継続中の議論もたくさんありますが(github.com/interagent/http-api-design/issues)、私たちはさらに学び、他の開発者がそれを承認しながら、ドキュメントを明確化し、進化させ続けています。
InfoQ: なぜPUTやDELETE操作でリソース全体を返すことを推奨しているのですか?
WB: 例外というのは、インターフェイスやガイドラインの敵です。リソース全体を返すことが望まれる場合はありますが、それが省略されるのはたいてい最適化の場合です。これをオプションの選択可能な振る舞いにしても、たいていの場合はうまくいくでしょうが、簡単で有用なデフォルトがあることが重要なのです。とは言え、これには異論もあって、その利点と欠点について突っ込んだ議論が続いています(https://github.com/interagent/http-api-design/issues/9)。
InfoQ: なぜISO8601形式のUTC時刻だけを使うのですか?
WB: リソース全体を返すのと同じように、(例外なしに)一貫したルールがあることは、あなたがやろうとしていることの理由付けになり、設計時にやらなければならない判断を減らしやすくしてくれます。また、タイムゾーンというのはクレイジーで厄介なものです。私は数えきれないくらい、タイムゾーン関連のエラーに出くわし、また自ら引き起こしてきました。私たちは問題が減ることを期待して、既知のタイムゾーンと形式を一貫して使うことにしました。