« Rails勉強会@東京 第5回 | メイン | 888.com World Snooker Championship »
2006年04月17日 (月)
Controller#respond_toはWeb ApplicationとWeb Serviceの垣根をなくす!? [テクニカル]
昨日のRails勉強会のポジションペーパーの内容を起こしてみた。内容はほとんどヽ( ・∀・)ノくまくまーからのインスパイヤなんですが。なので詳しくは元記事を見てください。このblogの記事の流れとしてはずいぶん前の「RESTful Web Applicationの可能性」からの続きの内容という感じです。
Rails 1.1からの新機能として、Controller#respond_toというメソッドができた。どういうものかというと、
- HTTP/1.1リクエストヘッダ中のAcceptフィールドを見る
- Content-Typeに応じてリクエストのデータ形式を自動変換してくれる
- 従って、コントローラは同じロジック(action)で対応できる
- Acceptの種類(mimeタイプ)に応じて、実行する描画処理を指定できる
- "*/*"が指定された場合はrespond_toの最初の定義を実行する
respond_to do |type|
type.html { render }
type.yaml { render :text => @resource.to_yaml }
type.xml { render :text => @resource.to_xml }
end
さらにREST的インターフェイスを実現するために自前でコントローラを実装する。
class RestController < AbstractRestController
def resource
model_name = params[:model].camelize
model = eval(model_name) # *超危険*
if params[:id] # idがあればMember URI
id = params[:id]
@resource = model.find(id)
case request.method
when :get
# Retrieving a Resource
respond_to do |type|
type.xml { render :text => @resource.to_xml }
type.yaml { render :text => @resource.to_yaml }
#type.json { render :text => @resource.to_json }
#残念ながらtype.jsonはまだ対応していない
end
when :put
# Updating a Resource (省略)
when :delete
# Deleting a Resource (省略)
end
else # idがなければCollection URI
case request.method
when :get
# Listing Collection Members (省略)
when :post
# Creating a Resource
new_resource = model.new(params[params[:model].to_sym])
if new_resource.save
render_post_success(:id => new_resource.id)
else
render :text => new_resource.errors.full_messages.join("\n"), :status => 406
end
end
end
end
さらにroutes.rbをこんな感じに設定。
map.connect 'rest/:model/:id',
:controller => 'rest', :action => 'resource', :id => nil
/rest/<モデル名>/<ID> という統一されたURI(Atom ProtocolでいうMember URI)でリソースにアクセスでき、さらに"Accept: application/xml"をつけるとXMLで取得、"Accept: application/x-yaml"をつけるとYAMLで取得したりできる。(JSONのMIMEタイプにまだ対応していないのが惜しいが、application/javascriptでもいいかな)
さらに取得だけではなく、/rest/<モデル名>というURI(Collection URI)に"Content-Type: application/xml"をつけてXMLをPOSTすれば、通常のFORM形式に変換してデータをCREATEしてくれる(くまくまーでは「うまく動きませんでした」って書いてあるけど、Rails 1.1.2で動作を確認。ただしContent-Lengthヘッダが必要)。
アプリケーションのすべてがRESTである必要はないが(というか無理)、Ajaxで使われるインターフェイスなどはとくにこんな感じで簡単にRESTが使えると、Webアプリケーションが即Webサービスとしても使えるようになるのでうれしい。
参考:
トラックバック
このエントリーのトラックバックURL:
http://www.4bit.net/x/mt/mt-tb.cgi/113
コメント
さっぱり何言ってるかわかんなかったよ!w
あ。
Ajaxがオランダのサッカーチームなのは知ってる。
投稿者 アイダ : 2006年04月18日 09:45
あいださん、どうも~。
またスヌーカー連れてってくださいね!
投稿者 4bit : 2006年04月18日 21:16