REST におけるベストプラクティス

スポンサーリンク

REST API の記事は, 今となっては普通にありふれています.

ほとんどのWEBアプリケーションの一部として利用されています.

シンプルで, 一貫性のある, 実用的なインターフェイスが必須で, そうであれば, 他の人が使う場合にかなり簡単にAPIを使うことができます.

これらのプラクティスが当たり前に思うかも知れませんが, よくこれを順守していない人をよく見かけますのでこの投稿を書くことにしました.

figure001

これらは RESTful API を設計するときに心に止めておくプラクティスです.

お断り:
これらのプラクティスは私の過去の経験から生まれたものです.
もし, あなたがそうは思わなければ,気軽にメールを送ってください.
そしてそれについて議論しましょう.

 

APIのバージョン

APIのバージョンは必須にすべきです. これは, 将来, APIの時系列変化の記録となります.

ひとつの方法としてはURLのパス部分にそれを含める方法があります.

/api/v1/…

もうひとつの方法としては, HTTPヘッダ Accept を利用する方法です.
GitHub でも使われています.

バージョンを使うことで, 古いクライアントとの互換性を気にすることなくAPI構造を変更できるようになります.

 

「動詞」でなく「名詞」を使う

「名詞」でなく「動詞」をリソース名に使っているのをよく見かけます.

悪い例 :

/getProducts
/listOrders
/retreiveClientByOrder?orderId=1

簡潔でわかりやすい構造として「名詞」を使うべきです.
HTTPメソッドを上手に使えばリソース名からアクション部分をなくすことができます.

良い例 :

GET /products : product の全リストを返す
POST /products : product を追加する
GET /products/4 : product #4 を取得する
PATCH/PUT /products/4 : product #4 を更新する

 

「複数形」を利用する

単数形と複数形のリソース名を混合するのはよくないです.
すぐに混乱して一貫性がなくなります.

アクションが show/delete/update だとしても
/artist は使わず /artists を使う.

 

GET / HEAD の利用は常にセーフティに使う

RFC2616 では, HEAD / GET メソッドは, 常にセーフティであるべきだと示されています. (ステータスの変更はすべきでない)

悪い例 :

GET /deleteProduct?id=1

検索エンジンのページインデックスを想像してみてください.

 

リソースのネストを利用する

コレクション内のコレクションを取得したいとき, 簡潔な設計として、ネストされたルーティングを使用します。

特定のアーティストのすべてのアルバムのリストを取得したい場合 :

GET /artists/8/albums

 

ページング

HTTP上で非常に大きな結果セットを返すことはいい考えではありません。
巨大なJSONをシリアライズすることは高コストとなり, 最終的にパフォーマンスの問題となります.

それを回避するために「ページ分割」が1つの選択肢となります.
Facebook, Twitter, Github などもそうしており,
短時間の複数回の呼び出しは, 一回の巨大な大変遅い実行より大変効果的です.

また, ページネーションを使用している場合にも、リンクのHTTPヘッダーに、
次と前のページのリンクを示しておくことは1つの良い方法です。GitHubもそうしています.

 

適切な HTTPステータスコード を利用する

コンテンツを返す際には、Success/Error のリクエスト両方に対して必ず適切なHTTPステータスコードを使用して返します.

以下, アプリケーションで利用できるコードの簡単なリストです.

Success codes

201 Created should be used when creating content (INSERT),
202 Accepted should be used when a request is queued for background processing (async tasks),
204 No Content should be used when the request was properly executed but no content was returned (a good example would be when you delete something).

Client error codes

400 Bad Request should be used when there was an error while processing the request payload (malformed JSON, for instance).
401 Unauthorized should be used when a request is not authenticiated (wrong access token, or username or password).
403 Forbidden should be used when the request is successfully authenticiated (see 401), but the action was forbidden.
406 Not Acceptable should be used when the requested format is not available (for instance, when requesting an XML resource from a JSON only server).
410 Gone Should be returned when the requested resource is permenantely deleted and will never be available again.
422 Unprocesable entity Could be used when there was a validation error while creating an object.

なお, RFC2616 でステータスコードの全リストを見ることができます.

 

常に一貫してエラーペイロードを返す

例外が発生したとき、一貫して常にエラーを説明するペイロードを返します。
こうすることで, どのエラーメッセージも(構造は常にエラーが何であれ同じ)パースが容易になります。

以下は, 私がよくWebアプリケーションで使用するものです。
それは、明確でシンプルに内容を説明しています。

HTTP/1.1 401 Unauthorized
{
“status”: “Unauthorized”,
“message”: “No access token provided.”,
“request_id”: “594600f4-7eec-47ca-8012-02e7b89859ce”
}

 

追記

などとえらそうに書きましたが全ては以下の意訳です.

Some REST best practices
https://bourgeois.me/rest/

改めて, 心に深く刻むことができたように思います.