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/

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


関連ワード:  WEBおすすめ開発


twitter.com が「This webpage is not available」となり見えなくなった場合の対処法

なぜか見えなくなった.

パソコン上の Chrome だけ.

ughughugh

Twitter側が落ちてるのかと思ったが, そうでもない.

API_Status___Twitter_Developers

API Status | Twitter Developers

対処法は, twitter.com の cookie を消すときれいに治る.

Settings_-_Cookies_and_site_data

結構, そんな状況の人多いみたいですわ.

きもい.


君たちの WordPress は shellshock 対策をしたのか!?

実質, ウワモノのPHPスクリプトで動くブログパッケージの問題ではないですけど.

Shellshock_-_Nam_'67

Troy Hunt: Everything you need to know about the Shellshock Bash bug

サーバとかよく分からず, ウワモノの WordPress のみで頑張ってる人はプラグインとかありますわ.

チェッカーとして使えます.

入れたらボタン押すだけ.

プラグインを追加_‹_新___android_ファッション通信_Σ_^A^;__—_WordPress

Shellshock_Vulnerability_Check_‹_新___android_ファッション通信_Σ_^A^;__—_WordPress

bash アップデート後にやってみたので, 問題なし.

Shellshock_Vulnerability_Check_‹_新___android_ファッション通信_Σ_^A^;__—_WordPress 2

WordPress › Shellshock Check « WordPress Plugins

詳しいことはよくわからないけど, ここらに書いてる.

CVE-2014-6271

CVE-2014-7169

サーバ内に入れる人は以下で「VULNERABLE」と表示されたらアウト, と.

ほとんど該当してるんじゃないかと思うけど.

env x='() { :;}; echo VULNERABLE' bash -c 'echo hello'

対策は, bash をアップデートするだけ.

yum update bash
apt-get install --only-upgrade bash

対策(アップデート)前だと,

# env x='() { :;}; echo VULNERABLE' bash -c 'echo hello'
VULNERABLE
hello

対策(アップデート)後だと,

# env x='() { :;}; echo VULNERABLE' bash -c 'echo hello'
hello

らしい.

環境変数から, bashコマンドを実行するようです.

ちと, さきほどのPHPで書かれたWPプラグインのコードを見てみる.

以下抜粋.

// CVE-2014-6271
$env = array('SHELL_SHOCK_TEST' => '() { :;}; echo VULNERABLE');
$desc = array(
    0 => array('pipe', 'r'),
    1 => array('pipe', 'w'),
    2 => array('pipe', 'w'),
);
$p = proc_open('bash -c "echo Test"', $desc, $pipes, null, $env);
$output = stream_get_contents($pipes[1]);
proc_close($p);
if (strpos($output, 'VULNERABLE') === false) {
    return false;
} else {
    return true;
}

// CVE-2014-7169
$desc = array(
    0 => array('pipe', 'r'),
    1 => array('pipe', 'w'),
    2 => array('pipe', 'w'),
);

$p = proc_open(
    "rm -f echo; env 'x=() { (a)=>\' bash -c \"echo date +%Y\"; cat echo", 
    $desc, $pipes, sys_get_temp_dir()
);
$output = stream_get_contents($pipes[1]);
proc_close($p);

$test = date('Y');

if (trim($output) === $test) {
    return true;
} else {
    return false;
}

true となれば, アウチサバ.

このプラグイン的には,PHPの関数「proc_open()」を使ってやってようですが, 他にもあるはず, shell 実行系の関数.

...
- system — 外部プログラムを実行し、出力を表示する
- exec() - 外部プログラムを実行する
- passthru() - 外部プログラムを実行し、未整形の出力を表示する
- popen() - プロセスへのファイルポインタをオープンする
- escapeshellcmd() - シェルのメタ文字をエスケープする
- pcntl_exec() - 現在のプロセス空間で指定したプログラムを実行する
- バックティック演算子
...

PHP: system - Manual

アプリ開発者 vs サーバ管理者で「おまえらがやれよ」とか不毛なことになったり,

大した理由もなしに, LLからshell叩くようなアプリを作ってたり.

 なお、ソースコードからのコンパイルではなく、ディストリビューターが配布しているbashパッケージを導入すれば、CVE-2014-6277/6278として報告されている脆弱性以外は影響を受けない事実を確認できたことも併せて発表している

ニュース - 「ShellShock」は公式パッチでは不十分、JPCERT/CCが追加の注意喚起:ITpro

Shellshockの影響が及ぶケースをまとめてみた - piyolog

けどまあ, それぞれ, いろいろな事情があったりして, いろんなレイヤーで対応策を知ってたほうが, きっとうまくいくだろうと.