ラックとは?
rack gemの作者であるChristian Neukirchenによると、RubyをサポートするWebサーバー(WEBrick、Mongrelなど)とruby Webフレームワーク(Rails、Sinatraなど)を接続するための最小限のAPIを提供するために作成されました。
Sinatraなどのフレームワークは、ラックの上に構築されるか、Webアプリケーションサーバーが接続できるようにするラックインターフェイスを備えています。
ラックの目的は単純です-HTTPリクエストの処理が簡単になります。
HTTPは単純なプロトコルです。基本的に、サーバーに送信され、クライアントに返されるデータの形式を記述します。 HTTP要求とHTTP応答の構造は非常に似ています。 HTTPリクエストは、メソッドとリソースのペア、一連のヘッダー、リクエスト本文で構成されるトリプルです。一方、HTTP HTTPレスポンスは、レスポンスコード、一連のヘッダー、オプションのレスポンス本文で構成されます。
Mapping Rackはそれに近いです。 Rackアプリケーションは、単一の引数(環境)を取り、ステータス、ヘッダー、応答本文の3つの要素の配列を返す呼び出しメソッドを持つルビーオブジェクトです。
ラックには、ハンドラーとアダプターが含まれています。 前者はRuby Webサーバーに接続し、後者はフレームワークに接続します。
ミドルウェアを使用すると、アプリケーションのニーズに合わせてラックを変更できます。 ラックミドルウェアの主な考え方は、要求がアプリケーションに入る前に処理し、応答を処理してからクライアントに返すことです。
ドキュメント
rack.rubyforge.org/doc
ラックを設置
この記事に記載されているものはすべて、Windowsにインストールされたruby 1.9.2でテストされていることに注意してください( host- master- およそPer。 )。
ラックが設置されているか確認してください。 これを行うには、コンソールを開きます。
# irb --simple-prompt
>> require 'rack'
=> true
requireがtrueを返す場合、ラックが取り付けられています。 そうしないと、次のようなエラーメッセージが表示されます。
LoadError: no such file to load -- rack
これは、gem install rackコマンドによって簡単に修正されます。
procオブジェクトのクイックツアー
procオブジェクトを覚えていますか? ルビーでは、ブロックはオブジェクトではありませんが、Procクラスのオブジェクトに変換できます。 これは、Objectクラスのラムダメソッドを呼び出すことで実行できます。 ラムダを使用して作成されたブロックは、ルビーメソッドのように動作します。 また、Procクラスにはcallメソッドがあり、実行のためにブロックを呼び出します。
>> my_rack_proc = lambda {puts 'Rack Intro'}
=> #<Proc:0x1fc9038@(irb):2(lambda)>
>> # method call invokes the block
?> my_rack_proc.call
Rack Intro
=> nil
最も単純なラックアプリケーション-my_rack_proc
既に述べたように、ラックアプリケーションは、呼び出しメソッドに応答するオブジェクト(クラスではなく)であり、1つの引数-環境(環境でもあります- 約 )を取ります 。 環境はHashクラスのインスタンスでなければなりません。 アプリケーションは、3つの値の配列を返す必要があります:ステータスコード(100以上)、ヘッダー(ハッシュ)、および本文(通常、本文は文字列の配列、アプリケーションインスタンス、またはファイルです。応答本文は各メソッドに応答し、文字列値のみを出力する必要があります)。 新しいprocオブジェクトを作成します。
>> my_rack_proc = lambda { |env| [200, {}, ["Hello. The time is #{Time.now}"]] }
=> # <Proc:0x1f4c358@(irb):5(lambda)>
これで、my_rack_procを呼び出すことができます。
>> my_rack_proc.call({})
=> [200, {}, ["Hello. The time is 2011-10-24 09:18:56 +0530"]]
my_rack_procは、単一ラインのラックです。
上記の例では、ヘッダーに空のハッシュを使用しました。 代わりに、次のようにヘッダーに何かを入れましょう。
>> my_rack_proc = lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
=> #<Proc:0x1f4c358@(irb):5(lambda)>
>> my_rack_proc.call({})
=> [200, {"Content-Type" => "text/plain"}, ["Hello. The time is 2011-10-24 09:18:56 +0530"]]
任意のハンドラーを使用してラックアプリケーションを実行できます。
どのタイプのハンドラーが利用可能か見てみましょう:
>> Rack::Handler.constants
=> [:CGI, :FastCGI, :Mongrel, :EventedMongrel, :SwiftipliedMongrel, :WEBrick, :LSWS, :SCGI, :Thin]
WEBrickを使用するには(デフォルトではWEBrickはRubyでインストールされたサーバーです)、次のように入力します。
>> Rack::Handler::WEBrick
=> Rack::Handler::WEBrick
これらすべてのハンドラーには、ラックアプリケーションを起動するrunメソッドがあります。
>> Rack::Handler::WEBrick.run my_rack_proc
[2011-10-24 10:00:45] INFO WEBrick 1.3.1
[2011-10-24 10:00:45] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 10:00:45] INFO WEBrick::HTTPServer#start: pid=1788 port=80
ブラウザでlocalhostページを開くと、次のような行が表示されます。
こんにちは 時間は2011-10-24 10:02:20 +0530
注:既にポート80で何かを実行している場合は、別のポートでアプリケーションを実行できます。
>> Rack::Handler::WEBrick.run my_rack_proc, :Port => 9876
[2011-10-24 11:32:21] INFO WEBrick 1.3.1
[2011-10-24 11:32:21] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 11:32:21] INFO WEBrick::HTTPServer # start: pid = 480 port = 9876
別のラックアプリケーションはmy_methodです
ラックアプリケーションは必ずしもラムダではありません。 メソッドにすることもできます。
>> def my_method env
>> [200, {}, ["method called"]]
>> end
=> nil
>> Rack::Handler::WEBrick.run method(:my_method)
[2011-10-24 14:32:05] INFO WEBrick 1.3.1
[2011-10-24 14:32:05] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 14:32:05] INFO WEBrick::HTTPServer#start: pid=1644 port=80
localhostで再び表示されます:
呼び出されたメソッド
メソッドオブジェクトはObject#メソッドを使用して作成されます。 これらは特定のオブジェクトに関連付けられています(クラスだけではありません)。 オブジェクト内のメソッドを呼び出すために使用できます。 Method.callは、指定された引数でメソッド( Oh、hack、hack ...- 約Per。 )を呼び出し、呼び出されたメソッドが返す値を返すメソッドです。
ラックアップを使用する
宝石ラックには、開発者の生活を簡素化する便利な部品が多数付属しています。 これらの部品の1つがラックアップです。
Rackupは、ラックアプリケーションを起動するための便利なツールです。 Rackup自体が実行環境を決定し、FastCGI、CGI、またはMongrelまたはWEBrickを使用したスタンドアロンとしてアプリケーションを実行します-すべて同じ構成です。
rackupを使用するには、構成ファイルを作成する必要があります。 慣例により、この構成には.ru拡張子を使用する必要があります。 デフォルトでは、ラックアップはポート9292で開始されます。
以下を含むconfig.ruファイルを作成しましょう。
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
このファイルにはrunという単語が含まれています 。これは、.callメソッドに応答するすべてのものから呼び出すことができます。
config.ruファイルがあるフォルダーでラックアプリケーションを起動するには、次のように入力します。
$ rackup config.ru
[2011-10-24 15:18:03] INFO WEBrick 1.3.1
[2011-10-24 15:18:03] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 15:18:03] INFO WEBrick::HTTPServer # start: pid = 3304 port = 9292
ここで、 localhost :9292 /で、次のページが再び表示されます。
Hello. The time is 2011-10-24 15:18:10 +0530
アプリケーションをconfig.ruファイルからmy_app.rbに移動しましょう。
# my_app.rb class MyApp def call(env) [200, {"Content-Type" => "text/html"}, ["Hello Rack Participants"]] end end
config.ruも変更します。
require './my_app' run MyApp.new
これで、「rackup config.ru」を使用してアプリケーションを再び起動し、ページがブラウザに送信されたかどうかを確認できます。
Herokuにラックアプリケーションをデプロイします。
(この記事の一部は、Windowsにgitをインストールし、herokuに展開することを説明しているため、冷酷に切り取られました。記事自体とは関係ありません。興味がある場合は、元の記事( 約Per )で読むことができます)
ラックミドルウェアの使用
サーバーとフレームワークの間で、ミドルウェアを使用してニーズに合わせてラックを構成できることは前述しました。
Rackupは、ミドルウェアを受け入れる方法も使用します。 組み込みのラックミドルウェアの1つを使用してみましょう。
config.ruまたはmy_app.rbファイルを変更するたびに、WEBrickサーバーを再起動する必要があることに注意してください。 これはミドルウェアRack :: Reloaderを使用して回避できます。 config.ruを編集します。
require './my_app' use Rack::Reloader run MyApp.new
そして、my_app.rb:
# my_app.rb class MyApp def call(env) [200, {"Content-Type" => "text/html"}, ["Hello Rack Participants from across the globe"]] end end
アプリケーションを起動し、ブラウザでページを開きます。 テキストを「世界中のHello Rack参加者!」から「世界中のHello Rack参加者!」に変更します。ブラウザーでページを更新すると、Webサーバーを再起動せずに編集したテキストが表示されます。
独自のミドルウェアの作成
ミドルウェアは、実際には常に内部アプリケーションをラップするのに役立ちます。
http応答の本文にテキストを追加する最も単純なミドルウェアを作成しましょう。 これを行うには、MyRackMiddlewareクラスを作成します。
class MyRackMiddleware def initialize(appl) @appl = appl end def call(env) end end
上記のコードでは、最初の応答本文を取得するために、MyRackMiddlewareクラスを初期化し、アプリケーション(appl)をそれに渡します。
.callメソッドを変更します。
def call(env) status, headers, body = @appl.call(env) # we now call the inner application end
上記のコードでは、元の応答本文にアクセスできますが、これを変更できます。 ラックは、本体がストリングであることを保証しません。 オブジェクトにすることもできますが、.eachメソッドを呼び出すと、返されるものはすべて文字列になります。 これを.callメソッドで使用します。
def call(env) status, headers, body = @appl.call(env) append_s = "... greetings from RubyLearning!!" [status, headers, body << append_s] end
config.ruファイルを変更します。
require './my_app' require './myrackmiddleware' use Rack::Reloader use MyRackMiddleware run MyApp.new
アプリケーションを起動すると、ブラウザーに「世界中のHello Rack参加者... RubyLearningからの挨拶!!」が表示されます。
ラックとシナトラ
最後に、sinatraフレームワークでラックを使用する簡単な例を示します。
ラックミドルウェアを使用する簡単なアプリケーションmy_sinatra.rbを作成しましょう。
require 'sinatra' require './rackmiddleware' use RackMiddleware get '/' do 'Welcome to all' end
次に、アプリケーションからの要求を処理するためにコンソール時間に書き込む単純なミドルウェアクラスを配置しましょう。 rackmiddleware.rbファイルを作成します。
class RackMiddleware def initialize(appl) @appl = appl end def call(env) start = Time.now status, headers, body = @appl.call(env) # call our Sinatra app stop = Time.now puts "Response Time: #{stop-start}" # display on console [status, headers, body] end end
config.ruファイルを変更します。
require "./my_sinatra" run Sinatra::Application
( 次は、Herokaにデプロイする方法、gitを使用する方法などのテキストブロックです。おもしろいとは思わないでしょう- 約。 )
これで、各リクエストに対してアプリケーションを起動した後、およそ次の内容の行がコンソールに書き込まれます。
?[36m2011-10-26T05:40:06+00:00 app[web.1]:?[0m *** Response Time ***: 0.000297385
以上です。 ラックへのこのエントリを楽しんだことを願っています。 ハッピーラッキング!