Rails 2.0とFlex 3 beta3でRESTfulなBookmarkアプリを作ろう 3
今回は前回の最後にでてきた問題(新規追加時のエラー)とその回避方法についてまとめます。
問題の説明
Bookmarkを新規追加すると、エラーのダイアログが表示されます。
でも、最新のリストを再取得してみるとBookmarkの追加自体は成功しています。
つまり、新規追加の処理自体は成功しているのに、誤ってエラーダイアログが表示されるということです。
原因
HTTPステータスコード「201 Created」の扱いについてRailsとFlexにずれがあることが原因です。一般的なWebアプリにおいて、通常クライアントのリクエストが成功した場合はHTTPステータスコード「200 OK」が返されますが、RailsのRESTfulアプリにおいて新規生成(PUT)が成功したときは、201が返されるようです。ところが、Flexが201を受け取るとエラーとして処理してしまいます。
これをFlexのバグとして報告しましたが、微妙なとこではあります。というのは、201はHTTPのPUTメソッドが成功したときに返されるものと定義されるようですが、Flex(Flash Player)ではPUTメソッドは送信できません(GETとPOSTのみ可)。これは一般的なブラウザでも同じです。そこでRailsのRESTfulアプリではパラメータに"_method=PUT"が含まれたPOSTメソッドでPUTメソッドの代用ができることを利用して擬似的にPUTを実現しています。つまり実際Flexから送信されているのはPOSTメソッドなのでそのレスポンスにおいてFlexが201を考慮していないのは仕方が無いとも言えます。
ただ、今後FlexがRESTfulアプリのクライアントとして重要な地位を占めるためにも、これはぜひ対応してほしいとこです。FlexからPUTやDELETEをプロキシサーバなしに送信可能になったらなおよいですが。それはFlash Playerの制限で無理そうです。
回避方法
Flex側でHTTPServiceの代わりに、URLLoaderを使って、HTTPStatusEventを取って(この場合もioErrorになる)201の場合、例外処理をする手もあるが、ブラウザによっては取れない場合もあるらしいので、サーバ側で対応した方がいいでしょう。
つまり、現在201を返しているとこを修正して200を返すようにします。修正するファイルは[RAILS_ROOT]\app\controllers\にあるbookmarks_controller.rbです。これを以下のように修正します。
# bookmarks_controller.rb抜粋
# POST /bookmarks
# POST /bookmarks.xml
def create
@bookmark = Bookmark.new(params[:bookmark])
respond_to do |format|
if @bookmark.save
flash[:notice] = 'Bookmark was successfully created.'
format.html { redirect_to(@bookmark) }
#format.xml { render :xml => @bookmark, :status => :created, :location => @bookmark } # 201を返す
format.xml { render :xml => @bookmark, :location => @bookmark } # 200を返す
else
format.html { render :action => "new" }
format.xml { render :xml => @bookmark.errors, :status => :unprocessable_entity }
end
end
end
修正完了
これでRESTfulアプリの基本機能である、一覧取得(GET)、新規追加(PUT)、更新(POST)、削除(DELETE)がエラーなくできるようになりました。
次回は、このアプリをレンタルサーバのXREAにアップしてアプリを公開するとこまでやりましょう。
トラックバック(0)
このブログ記事を参照しているブログ一覧: Rails 2.0とFlex 3 beta3でRESTfulなBookmarkアプリを作ろう 3
このブログ記事に対するトラックバックURL: http://uenon.jp/mt/mt-tb.cgi/101

コメントする