RESTful Web アプリの
   設計レビューの話


  和田 卓人 (a.k.a id:t-wada or @t_wada)
    July 23, 2012 @ sendagaya.rb
結論:
REST は
麻疹である
(良いものなので早く感染して厨期を
      卒業しよう)
自己紹介
名前:     和田 卓人 (わだ たくと)

ブログ: http://d.hatena.ne.jp/t-wada

メール: takuto.wada@gmail.com

Twitter: http://twitter.com/t_wada

タワーズ・クエスト株式会社
取締役社長
私と REST (input)

• WEB+DB PRESS vol.32「REST
 アーキテクチャスタイル入門」

• はてぶ設計議論
• DHH の RubyKaigi 2006 Keynote
• WEB+DB PRESS vol.38∼「REST
 レシピ」

• 『RESTful Web Service』
私と REST (output)

• Java でいろいろ実装 (JSR311関係)
• WEB+DB PRESS vol.42 「Restlet で動
 かしながら学ぶ REST の世界」執筆

• 動画で配信!「現場で使えるREST」鼎談
• 『Web を支える技術』トークセッション
おことわり:
Rails の話は
あまりしません
(REST の話ばっかりします)
URL 設計レビューを行ったプロジェクト

•規模が大きい rails プロジェクト
  • route 数 1000 以上
•レビューツール
  • ホワイトボード
  • チャット
  • Wiki
  • diff
RESTful アプリ設計のステップ
1. 対象となるデータを認識する

2. 対象となるデータをリソースに分ける

(2 で分けたひとつひとつのリソースに対して)

3. リソースにURLで名前を付ける

4. リソースに対して統一インターフェイスのサブセットを提供する(GET/
   POST/PUT/DELETE をマッピング)

5. クライアントから受信する表現(Representation)を(一つ以上)設計する

6. クライアントに提供する表現を (一つ以上) 設計する

7. ハイパーメディアリンクとフォームを使用して、このリソースを既存のリ
   ソースに統合する (接続性 = Connectedness を高める)

8. 正常系を考える(適切なリクエストがあったとき何が起こるべきか)

9. 例外条件を考える(不適切なリクエストがあったとき何が起こるべきか)
設計レビューで見るポイント

• URL 設計 (動詞、構造、クエリ)
 • CRUD の重力に引かれていないか
• HTTP メソッドの選択
• ステータスコードの選択
• 表現の設計
 • 情報量に過不足は無いか
 • 接続性を満たしているか
URL に動詞が含まれていないか

  GET http://example.com/blog/getEntries
○ GET http://example.com/blog/entries


  POST http://example.com/blog/entries/add
○ POST http://example.com/blog/entries


  POST http://example.com/blog/entries/30/delete
○ DELETE http://example.com/blog/entries/30
URL に動詞が含まれていないか



• add, delete, update =>
• edit => △ (規約による妥協)
• なるべく名詞に近づける努力をする
 • confirm -> confirmation
• 名詞と動詞が同じ形のものは状況による
URL が無理な構造になっていないか

• Tumblr の奇妙な URL
 • http://www.tumblr.com/show/everything/by/me
 • それっぽく読めれば良いというものではない

• example.com/files/copy/:source/:destination =>
 • コピー先はコピー元と従属関係が無い(階層構造は不当)

• URL が右にいくに従って自然な階層構造/サブセットに
  なっているか
URL が無理な構造になっていないか

• URL 設計のほとんどの時間は「名前を探す」ことに費や
 される

  • いつも辞書と共に設計する
• リソースとリソースの関係を表す第三のリソースを探す
   • subscription, belonging, tagging
• リソースは DB レコードだけでは無い
   • トランザクション
   • 計算結果
URL の意味と意思


http://example.com/blog/entries?page=3&lang=ja

          リソースの意味               クライアントの意思




• 「サーバ上の意味」と「どう見たいかという意思」
• ? 以降をすべて取り去っても意味は変わらないか
• ? 以前にリソースの意味と関係ない要素は無いか
CRUD の重力に引かれていないか

• GET/POST/PUT/DELETE を DB の
 SELECT/INSERT/UPDATE/DELETE に
  1:1 に自動的に 対応させるのは思考停止

 • 1:1 とは限らない
 • 多くの意味と表現を持つテーブルもある
    • テーブルの重要度には濃淡がある
 • 従属的で個別の意味と表現を持たないテーブ
  ルもある
CRUD の重力に引かれていないか



• 第3正規形のテーブルと 1:1 の route がある
 のは粒度が細かすぎる

  • N+1 Problem にも容易に突き当たる
• リソースの粒度/視点(つまりは URL)とデータ
 ベースの粒度/視点の違いを解釈してしかるべ
 く結びつけるのが Controller の仕事
HTTP メソッドの選択

• URL で示されるリソースに対して「何をし
 たいか」で GET/POST/PUT/DELETE

  • ここで揉めることは少ない
• GET 重要。とても重要。
• リソースを作る場合
   • URL が新たに作成される場合は POST
   • URL がわかっている場合は PUT
• どうにもならなくなったら POST に倒す
ステータスコードの選択

• 意識的に使用するコードは概ね次のものに収
 束する

 • 200, 201, 204
 • 301, 303, 307, (304)
 • 400, 404, 409, (401, 403)
 • 500
• クライアント側が悪いときは 400 系、サー
 バ側が悪いときは 500 系
ステータスコードの選択




• 例外系 (400/500系) は controller / model
 から投げる例外をステータスコードにマッピ
 ングする(これは rails の話)

• クライアントに対してリソースを隠匿するか
 どうかで 400 系を 404 に倒すこともある
表現の設計

• URL、あるいは URL の作り方(つまり
 フォーム)が含まれていること

  • 袋小路になっていないこと
• GET のパラメータを組み立てさせたいとき
 はフォームを使う (フォームは POST のため
 だけじゃないよ)

• js 側で文字列を結合して URL を作るのでは
 なく、 URI-Templates を渡す

  • http://tools.ietf.org/html/rfc6570
表現の設計



• Content Negotiation
   • Accept や Accept-Language ヘッダ
   • 表現のフォーマットは URL に含められ
    るとなお良い

  • 表現の言語選択(ja,en,...)も URL に含め
    られるとなお良い
接続性ある表現のために


• クライアントは、サービスから送られてくる表現の中に含
 まれているリンク(またはフォーム)を使用することによっ
 てのみ、自分の状態を変更できる(簡単な例を挙げるな
 ら、リンクやフォームによってのみ、画面の状態を変える
 ことができる)

• サービスは、クライアントがURLを組み立てることを強
 制してはならないし、期待してはならない

• サービスは、以上の点をクライアントに無理なく守っても
 らうために、クライアントが次に取り得る状態をすべてリ
 ンク(またはフォーム)の形で表現に含める
議論
議論になるポイント


• やりたいこと vs. (Rails 的な)作りやすさ
• 確認画面、プレビュー画面、完了画面…
• リソースの移動、コピー
• トランザクションの表現
• 複数レコードを選択して更新する UI
   • 207 Multi-Status の誘惑
議論になるポイント

• URL に機械採番の id が含まれる
   • セキュアじゃ無い
   • 永続的でない(かも)
• API のバージョニング
   • 自前でやっていた
  •   https://github.com/bploetz/versionist 良さそう

• rails4 の PATCH メソッドどうよ?
議論になるポイント

• あまり非同期処理に頼らない
   • DOM Scripting の原則に従う
• RESTful なサーバとリッチ js という設計に
 倒しすぎると UX や保守性が低下する可能
 性があるので注意

  • REST 厨がみんな通る道
  • 一方 Twitter はリッチ js から戻した
• 制約をバランスすることこそが設計
参考文献
結論:
REST は
麻疹である
(良いものなので早く感染して厨期を
      卒業しよう)
ご清聴ありがとうございました




        http://lumberjaph.net/graph/2010/03/25/github-explorer.html

RESTful Web アプリの設計レビューの話