REST おさらい

  • REST はアーキテクチャスタイル
  • Web システムの設計の指針にできる
  • 特に HTTP と URI を正しく使うのが重要
  • 可用性と相互運用性

REST をどう使うか

  • 設計の参考として
  • Web システムの理解促進に
  • ボキャブラリの共有として
    • 「それステートレス?」
    • 「統一インターフェース使おうよ」

Web システム

  • Web を使ったシステム
    • Web アプリケーション(UI)
    • Web サービス
  • 両者を分ける意味はあまりない
    • むしろ分けずに済ますほうがよい
      • microformats
      • 人にもプログラムにもやさいしい XHTML

Web システムの設計

  • "ウェブ戦略としての「ユーザーエクスペリエンス」"より
    • ユーザインターフェースとしての Web
    • ハイパーメディアシステムとしての Web
  • Web はもともとハイパーテキストシステムだった
  • 近年は UI としての Web の技術革新が集中的
    • Ajax 周辺

ハイパーメディアシステムの設計

1 クール URI

  • by TBL
  • == 変らない URI
  • 元々はしばらくすると404になる URI が多すぎたから出てきた言葉

どうすればクールになるのか?

変わりにくい URI の設計のヒント

  • 実装に依存しない
    • *.pl とか
  • リソースは名詞
    • URI に action (get/set など)は入れない
  • セッションIDも入れない
  • なるべくイマドキのフレームワークを使う
  • Web アプリとWeb API で URI を分けない
    • /xmlrpc とかはよくない

REST 的には

  • URI はクライアントに不透明
  • クライアントが URI をいじったり推測するしかないのはダメ(密結合)
    • リンクをたどる
    • Form から query を投げる
  • URI template

1 URI まとめ

  • 変えないのが重要
  • 変えにくくする工夫
  • tkawa さんの map.resources 解説に期待

2 Web API

  • API?
  • プログラムから(ã‚‚)アクセス可能なリソース
  • リソース表現はさまざま

Web アプリと Web サービスを分けて考えない

件数取得API リクエスト

POST /xmlrpc HTTP/1.1
Host: b.hatena.ne.jp
Content-Type: text/xml

<methodCall>
 <methodName>bookmark.getCount</methodName>
 <params>
  <param>
   <value><string>http://d.hatena.ne.jp/</string></value>
  </param>
  <param>
   <value><string>http://b.hatena.ne.jp/</string></value>
  </param>
  <param>
   <value><string>http://www.hatena.ne.jp/</string></value>
  </param>
 </params>
</methodCall>

件数取得API レスポンス

HTTP/1.1 200 OK
Content-Type: text/xml
Content-Encoding: gzip

<?xml version="1.0" encoding="us-ascii"?>
<methodResponse>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>http://www.hatena.ne.jp/</name>
            <value><int>157</int></value>
          </member>
          <member>
            <name>http://b.hatena.ne.jp/</name>
            <value><int>198</int></value>
	  </member>
	  <member>
            <name>http://d.hatena.ne.jp/</name>
            <value><int>35</int></value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodResponse>

なんでこうなったか?

  • パラメータを複数渡さなければならない
    • URI ã‚’50件指定可能
  • GET では書けない
  • 複数パラメータを POST で渡せる XML-RPC

改善後リクエスト

POST /atom/exist HTTP/1.1
Host: b.hatena.ne.jp
Content-Type: application/xml

<uri-list>
  <uri>http://d.hatena.ne.jp/naoya/20051212</uri>
  <uri>http://yohei-y.blogspot.com</uri>
</uri-list>
POST /atom/exist HTTP/1.1
Host: b.hatena.ne.jp
Content-Type: application/x-www-form-urlencoded

uri0=http://d.hatena.ne.jp/naoya/20051212&uri1=http://yohei-y.blogspot.com

改善後レスポンス

HTTP/1.1 201 Created
Content-Type: application/atom+xml
Location: http://b.hatena.ne.jp/atom/exist/1234567890abcdefg

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>はてなブックマーク検索結果</title> 
  <link rel="self" type="application/atom+xml"
    href="http://b.hatena.ne.jp/atom/exist/1234567890abcdefg"/>
  <updated>2003-12-13T18:30:02Z</updated>
  <author><name>Hatena</name></author> 
  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>

  <entry>
    <title>なおやのはてなダイアリー</title>
    <link href="http://d.hatena.ne.jp/naoya/20051212"/>
    <link rel="alternate" href="http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/naoya/20051212"/>
    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
    <updated>2005-12-13T18:30:02Z</updated>
    <summary>5</summary>
    <content type="xhtml">
      <!-- リンク、キーワード、タグなんかをそのまま入れる -->
    </content>
  </entry>

  <entry>
    <title>yohei-y:weblog</title>
    <link href="http://yohei-y.blogspot.com"/>
    <link rel="alternate" href="http://b.hatena.ne.jp/entry/http://yohei-y.blogspot.com"/>
    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
    <updated>2005-12-10T10:34:02Z</updated>
    <summary>4</summary>
    <content type="xhtml">
      <!-- リンク、キーワード、タグなんかをそのまま入れる -->
    </content>
  </entry>

</feed>

レスポンスは JSON でも JSONP でも

HTTP/1.1 201 Created
Content-Type: application/json
Location: http://b.hatena.ne.jp/atom/exist/1234567890abcdefg

{
 "http://d.hatena.ne.jp/naoya/20051212": 5,
 "http://yohei-y.blogspot.com" : 4
}

良い例 ブックマーク数を画像で取得する API

リクエスト(ブックマーク数リソース)

GET /entry/image/http://d.hatena.ne.jp HTTP/1.1
Host: b.hatena.ne.jp

レスポンス

HTTP/1.1 200 OK
Content-Type: image/png

binary data

本当の動きは

HTTP/1.1 302 Moved Temporarily
Location: http://b.hatena.ne.jp/images/users/normal/00036.png
GET /users/normal/00036.png
Host: b.hatena.ne.jp
HTTP/1.1 200 OK
Content-Type: image/png
Etag: "d7a218-1f9-f35b8700"

binary data

画像をGETするとキャッシュにヒット

GET /users/normal/00036.png
Host: b.hatena.ne.jp
If-Modified-Since: Fri, 07 Jul 2006 08:54:03 GMT
If-None-Match: "d7a218-1f9-f35b8700"
HTTP/1.1 304 Not Modified
Content-Type: image/png
Etag: "d7a218-1f9-f35b8700"

なにが良い?

  • キャッシュを有効利用
  • レスポンスコードを正しく利用
  • HTML から img/@src でリンク可能!
    • Web アプリと Web サービスを分けて考えていない
  • 細かいツッコミ
    • 302 は Found じゃないの? (RFC2616)
      • Moved Temporarily は RFC 2068
    • Expires を指定した方がいいかも

はてなブックマークAPIの分析

  • 件数取得の敗因(推測)
    • 初めにメソッドコール的に考えた?
    • フォーマットで悩んでしまった
  • 画像取得の勝因(推測)
    • img 要素からの利用(リンク)が念頭に?

Web API 設計のヒント(1)

  • 1 リソースとその URI を基準に
    • resource oriented
    • 自分の Web サイトから提供したいリソースは何か?
    • HTML/Atom からリンクしてうれしくないか?
      • a/@href, img/@src, script/@src, link/@href

Web API 設計のヒント(2)

  • とりあえず XML-RPC はもうやめよう
  • 無理して XML を使うのはやめる

リソース表現選択の手法

  • 残念ながら決定的な手法は知らない
  • 経験+センスがものを言う世界
  • 「デファクト」重要
  • 「真似」重要
  • センスの良い API を真似しよう
    • GData, Hatena APIs

3 最近の REST 関係の話題(1)

  • REST 本
    • 来年5月?
    • 今日話したような内容をより包括的に
    • SOA への対抗イデオロギーとしての ROA

最近の REST 関係の話題(2)

  • blog で対話形式がはやってます
    • REST Dialogues by Duncan Cragg
      • 9個の予定(現状二つ)
    • The S stands for Simple by Pete Lacey
      • ほとんど訳したんだけど最後の一文が訳せず挫折中orz

最近の REST 関係の話題(4)

  • uddi public directory 終了 2005/12
  • 変な REST 解説も多数
  • REST/WS-* 使いわけ論 2006/02
  • 良い API もたくさん
  • APP まだ RFC にならない
    • もうすこし

REST vs SOAP/WS-*(ROA vs SOA)

  • 表面的な違い
    • 仕様の数
    • 大ベンダの思惑
  • 本質的な違い
    • 統一インターフェース vs 個別インターフェース
    • 複雑な MEP (Message Exchange Pattern) が必要かどうか

できなかった話

  • 認証まわり
    • まだこなれてない
  • エラーの話
    • torum さんごめんなさい
    • atom entry + hError?

まとめ

  • RESTful なシステムが増えてきた
  • 今後ますますデータが重要に
    • Web API の可能性は広がる
    • データを Web に解き放て
  • Web アプリと Web サービスを分けて考えない