2011年11月30日水曜日

Maas : Middleware as a Service

Amazonのクラウド環境(以下、AWS)上に、Railsアプリを作成する場合、
メインのデータベースを何にするかの選択肢がいくつかあります。
大きくは以下の二つが考えられると思います。
  1. 自前でDBサーバを運用する
  2. AWSのDBサービスを利用する
1の選択肢はオンプレミスでRailsアプリを作る場合と同様です。MySQLやPostgreSQL等のRDBの中から好みの製品を選んで、EC2上で運用することになります。
2の選択肢は、AWSならではの選択肢です。AWSでは以下のDBがWebサービスとして提供されています。
これらを、SaaSやIaasといった言葉に習って、Middleware as a Service => Maas [マース] って呼ぶのはどうでしょう?既存のIaasともPaasともちょっと違うので、Maasがしっくりくる気がします。

AWSにはこのようなMaasがいっぱいあります。AWSといえば、EC2やS3といったIaasやHaasのイメージが強かったのですが、単なるハードウェアリソースを提供するサービスだけでなく、このようなアプリケーションレイヤーよりの便利なサービスもあるんですね。

2011年11月27日日曜日

Railsの擬似RESTにPut/Deleteを投げる2つの方法

前置き

RailsではRESTfulなインターフェースが基本です。
RESTfulの設計思想では、以下のように処理によってhttpのメソッドの使い分けをすることとされています。

  • データを参照したいときは、GET
  • データを新規登録したいときは、POST
  • データを更新したいときは、PUT
  • データを削除したいときは、DELETE


しかし、現状では、ブラウザはPUT、DELETEメソッドを実装していません。
つまり、現在のWeb環境では、純粋なRESTfulインターフェースを使うことはできないのです。

仕方ないので、Railsでは、
PUT/DELETEをしたいときは、httpのメソッド的にはPOSTを使いながらも、
これはPUTです、これはDELETEです、というフラグを合わせることで、
RESTfulっぽいインターフェースを実現しています。
これが擬似REST方式です。


このあたりはRailsのフレームワークが隠蔽してくれるので、
アプリのプログラマは普段はあまり意識する必要はありません。


ただし、先日、これを強く意識する必要に迫られることがあったので、メモ。

RailsアプリのクライアントがWebブラウザである場合は、何も意識する必要はありません。Web画面のsubmitボタンを押せば、それがPutなのか、Deleteなのか分かるように、Railsがhtmlを作ってくれているからです。大抵のRailsアプリのクライアントはWebブラウザですね。

そうではなくて、Railsアプリのクライアントを自作する場合が問題となります。
例えばどこか外部のWebAPI(Amazonの本屋のWebAPIとか)を利用する場合、そのサービスの使い方(インターフェース)を知る必要がありますよね?
その外部のWebAPIがRailsで作られたWebサービスなのであれば、RailsアプリのAPIを知らなければいけません。そのRailsアプリのAPIが擬似REST方式だとしたら、擬似RESTへのリクエストの投げ方を知らないといけないのです。
(Railsは基本、擬似RESTですが、Routingを自分で定義すれば擬似RESTでないAPIも自由に作れます。以下に説明するように、ブラウザ以外からGET/POST以外の擬似RESTを使うのは少し面倒なので、ブラウザ以外から利用することを主としたWebAPIで、PUT/DELETEを実装したいなら、無理して擬似RESTにしない方がいいと思います。)

Railsの擬似RESTにリクエストを投げる方法


前置きが長くなってしまった、、ここから本題です。
GET/POSTメソッドのリクエストを投げたいときは、そのままGET/POSTのhttpリクエストを投げればいいだけなので、省略します。以下、Railsの擬似RESTインターフェースに、PUT/DELETEメソッドのリクエストを投げる方法について説明します。

方法1:_methodパラメータを指定する。



clnt = HTTPClient.new
body = {
  'param1'=>'hoge',
  '_method'=>'put',
}
res = clnt.post(SERVER_URI, body)


方法2:X-Http-Method-Overrideを指定する。



req = Net::HTTP::Post.new(path, initheader = {'Content-Type' =>'application/json'})
res = Net::HTTP.new(HOST, PORT).start {|http|
  req["X-Http-Method-Override"] = "put"
  http.request(req)
}


Content-TypeにJsonを指定すると、なぜか方法1が使えなかった。
方法2ならいけました。

Rails3でグラフ

Ruby on Railsで見栄えのいいグラフを書きたいときに便利な、
Open Flash Chart 2というプラグインがある。
Rubyのコードで必要なプロパティを設定するだけで、
対応するswfファイル(Flash)を作成してくれる。
Rails3でこのプラグインを使おうとしたら、少しだけはまったのでメモ。

erbファイルの中の、グラフを出力したい部分に以下のように記述することで、Flash用のコードが出力されるのだが、

<%= @graph %>

Rails3ではデフォルトでhtmlタグのサニタイジングがonなので、htmlタグが自動でエスケープされてしまう。そこで、Rails3では、以下のように、サニタイジングをoffにする必要がある。

<%= raw @graph %>


Open Flash Chart 2、いいんだけど、html5の時代にFlashというところが残念、、
どこかにFlash抜きでかっこいいグラフを書いてくれるライブラリないかな。