傭兵日記

自己紹介

職業
ソフトウェアエンジニア(XML guy)
最近の興味
XML で記述する言語の設計一般。たとえば設計論(要素 or 属性)や、スキーマのバージョニング、仕様としてのスキーマの記述、などに興味あり。
REST にも興味あり。
連絡先
yamamotoyohei at yahoo dot co dot jp までお気軽にどうぞ

この日記に記述されている内容は、筆者の個人的な主張や考えであり、筆者の勤務する企業や属する組織とはまったく関係ないことをお断りしておきます。

2003 | 08 | 10 | 11 | 12 |
2004 | 03 | 04 | 05 | 06 | 08 | 09 | 10 | 11 |
2006 | 11 |
2008 | 12 |
 | 

2006-11-24 第九回XML開発者の日

自己紹介

  • 山本陽平
  • ソフトウェアエンジニア
  • XML guy
  • Restafarian
  • yoheiy at gmail.com

REST おさらい

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

REST をどう使うか

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

Web システム

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

Web システムの設計

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

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

アジェンダ

  • 1 クール URI の設計
  • 2 Web API の設計
  • 3 最近の REST 関連のトピック

1 クール URI

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

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

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

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

REST 的には

1 URI まとめ

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

2 Web API

  • API?
  • プログラムから(も)アクセス可能なリソース
  • リソース表現はさまざま
    • XHTML
      • microformats
    • image/*, application/*
    • Atom
    • JSON, JSONP

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

REST 的にどうするか

  • query document を POST
  • 201 レスポンスと Location ヘッダ

改善後リクエスト

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 要素からの利用(リンク)が念頭に?

リンク重要

  • リンク可能なもの == REST 的に正しいリソース

Web API 設計のヒント(1)

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

Web API 設計のヒント(2)

  • 2 そのリソースに適した表現は何か?
    • XHTML/microformats
    • image/*, application/*
    • 素 atom entry
    • 拡張タグつき atom entry
      • opensearch
    • JSON, JSONP
    • 独自マークアップ
  • とりあえず XML-RPC はもうやめよう
  • 無理して XML を使うのはやめる

リソース表現選択の手法

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

2 Web API の設計

  • おわり

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 関係の話題(3)

  • インタビュー at infoQ
    • Tim Bray
    • DHH

最近の 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 サービスを分けて考えない

ご静聴ありがとうございました

質問ありますか?

 | 
Connection: close