Showing posts with label Sinatra. Show all posts
Showing posts with label Sinatra. Show all posts

Monday, 29 October 2012

SinatraとRSpecで開発(ちょっとしんどい)

ここ2日程SinatraとRSpecを使って、1ページウェブサイトの制作をしていました。

Sinatraはとてもシンプルなのが好きで使っているのですが、少しやる事が複雑になると一つずつrequireを追加していく必要があります。フォームを設置する、外部APIを使用する、テストを書くという程度の制作になればSinatraではなくてRailsにしたほうがかなり時間を抑えて開発できるのではないでしょうか。小さな規模のサイトなのにかなり時間がかかりました。

例えばURLのパースにはURIを使い、外部APIを使うにはNet:HTTPを使い、メールの送信にはPonyかMailなどのgemを使用、viewのヘルパーもデフォルトでは便利なものが多くないので、Sinatra_moreのgemを引っ張ってくるという具合です。RSpecのテストをする際にもデフォルトではassignsやrender_templateなどの何気なく使用しているマッチャーも無く、カスタマイズが必要でした。メールの送信もあまりマニュアルが整備されていないgemを使う必要があり、コードを読みにいったりする必要がありました。

今回はいかにRoRが皆に支持されていろんな便利なツールを実装しているか知る良い機会になりました。それはそれでありがたい経験です。

Monday, 23 July 2012

Ruby は殆ど知らなくてもRoRは組めるのですが

RoRはRubyで書かれたフレームワークですが、フレームワークのパーツ(scaffoldやgemなど)を集めて組み立てればRuby自体は基本的なことだけ知っていればあり程度動くウェブアプリケーションは作ることができます。セキュリティーの面でも怖ければ、セッション管理などはライブラリに任せて触らないようにすれば難は逃れられるでしょう。 

良いフレームワークは矯正ギブスのようなもので、良い習慣を身につけるのに使えるという話を以前PHPerに聞きました。この意味でRoRはとても良いと思います。最近は、小さなウェブサービスの構築だとRoRを使わずにSinatraで作れるし、実はデータベースが必要なアプリケーションも単純にgemでActiveRecordやMongoIDのようなORマッパーさえ拾ってくればRoRはなくても組めるということにも気がつきます。

 

もっと自由にRubyを使えるようになりたいと思い、以前に買ったYugui著「はじめてのRuby」を引っ張り出してきたのですが、このコンテクストでは使えないようです。この本はRubyを学び始める人に有益なように譲りたいですね…。Rubyとソフトウェアのデザインパターンを一緒に習得できる書籍を見つけます。

 

 

Saturday, 21 July 2012

Sinatra で拡張子ごとにMIME-Type (と対応するContent-Type) を設定する

*.bin 拡張子のファイルを"audio/mpeg"としてサーバからヘッダを返さないとiOSで動画が再生されないという仕様のサービスがあり、Sinatraとthinで動かしているシステムの調整が必要になりました。

結論としては

configure do
  mime_type :bin, 'audio/mpeg'
end

と書けば解決しました。書式は

mime_type :<extension name>, '<mime type name>'

のようです。

Middlewareを間に挟んで調整するかthinもしくは.ruファイルを編集する必要があるかと考えたのですが、現在Sinatraはモジュールタイプで動かしていないので面倒です。しかし、とても簡単にSinatra上でメソッドが提供されていました。SinatraはMiddlewareとしても利用できるという話ですが、さすが httpヘッダ を調整するのは簡単にできるようです。

Thursday, 24 May 2012

SinatraとHerokuでフレキシブルな静的ファイルサーバ構築

SinatraとHerokuでフレキシブルな静的ファイルサーバ構築をしてみました。実際役に立つかどうか?というのは、用途によります。

SinatraもRailsもgemなどを使ってインストールさせ、サーバを起動すれば /public以下のフォルダをかってに拾ってくれるので、単純なhtmlのサイトであればお手軽に無料でサイトが作成できます。(無料でサイトを作成するという意味であればWordpressやFacebook, Google Pageなどいくらでも便利なつーるはあり、そちらの方が断然便利だと思います。)

Sinatraならではのフレキシブルな点としてはアプリケーションに

get "/folder_name/*"
  protect!
  File.read("/public/index.html")
end

などとすれば特定のフォルダを簡単にBasic認証で保護できます。

また、Amazon S3の上にファイルを置いて、下のようにすれば特定の(この場合は東北アジアのサーバに置いた)バスケットに見せたいファイルをアップロードすれば普通の静的ファイルサーバの様に見せてくれます。jpgでもhtmlでもpdfでも問題無いはずです。


require 'rubygems'
require 'sinatra'
require 'aws/s3'
include AWS::S3

helpers do
  def connect_aws_s3
    DEFAULT_HOST.replace "s3-ap-northeast-1.amazonaws.com"
    connection = Base.establish_connection!(
      :access_key_id     => 'YOUR-KEY-ID',
      :secret_access_key => 'YOUR-SECRET-ACCESS-KEY'
    )
    @bucket = Bucket.find('sinatra-aws-s3-test')
  end

  def protect!(user_name, passwd)
    unless authorized?(user_name, passwd)
      response['WWW-Authenticate'] = %(Basic realm="Restricted Area")
      throw(:halt, [401, "Not authorized\n"])
    end
  end

  def authorized?(user_name, passwd)
    @auth ||=  Rack::Auth::Basic::Request.new(request.env)
    username = user_name
    password = passwd
    @auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == [username, password]
  end
end

get %r{.+} do

  protect!("username", "password") if request.path.match(/^\/folder_name/)

  connect_aws_s3

  file_path = request.path
  file_path += "index.html" if file_path.match(/\/$/)
  file = @bucket[file_path.gsub(/^\//,"")] rescue throw(:halt, [404, "Page not found\n"])

  content_type file.content_type
  file.value
end

get %r{.+} do で全てのgetメソッドリクエストに対してアプリケーションが対応する様にしています。

ここで、確かに見せるだけは問題無いのですが、少し大きな動画などのファイルを見せると、S3 Bucketの読み込みに時間がかかるらしくレスポンスがかなり遅くなります。S3のBucketをアメリカのサーバに移しても同じでした。

なのでキャッシングを有効にするためにRack Middlewareを使います。http://rtomayko.github.com/rack-cache/
私の場合は 'rack-cache'と'dalli'のgem をインストールしてconfig.ruに

require 'rack/cache'
require 'dalli'


use Rack::Cache,
  :verbose     => true,
  :metastore   => Dalli::Client.new,
  :entitystore => 'file:tmp/cache/rack/body'


を加えると読み込みが断然改善されました。でもこうするとHerokuサーバ上に大きなキャッシュのファイルを置くことになるので、直接/publicの下にファイルを置くのと大差ありませんね。実験としては面白いと思いますが、実用的ではないかもしれませんね。

また、Herokuのアプリケーションを動かしているサーバからのレスポンスはサーバがアメリカにあるためこれ以上改善できなさそうです。この点はHerokuが日本のサーバでサーバを提供してくれるのを期待するしかなさそうです。