woshidan's blog

そんなことよりコードにダイブ。

Rackの概要、RackミドルウェアとRackアプリケーションの違いについて

この記事はRubyアドベントカレンダーの14日目の記事です。

最近Rackにさわることがあったのでこの記事では

についてまとめます。

Rack概要

RackはWebサーバとRuby及びRubyフレームワークとの間でやりとりをするためのインタフェースを提供するためのライブラリです。

具体的にはRackは

  1. Webサーバに来たリクエストを決まったキーを持つハッシュに加工し *1 、そのハッシュを引数にしてRubyで動いているアプリケーションのプログラムを呼び出す
  2. Rubyのアプリケーションから受け取る['200', {'Content-Type' => 'text/html'}, ['A barebones rack app.']] のような形式の配列を加工して、Webサーバが扱う変数に代入する

のはたらきをする Rack ハンドラー 、設定ファイルを読み込み、実行環境に合わせたWebサーバを起動する rackup コマンド、設定ファイルを書く際に利用する Rack::Builder DSL を提供し、

Rackハンドラーから呼び出されるRuby及びRubyフレームワークのアプリケーションプログラム側には

  • ハッシュを引数に call メソッドを呼ぶと ['200', {'Content-Type' => 'text/html'}, ['A barebones rack app.']] のような形式のレスポンスを返す

という規約( Rackプロトコル *2 )を守ることを要求します。

この規約に則ったRubyのオブジェクトを Rackアプリケーション と呼びます。

f:id:woshidan:20181214222452p:plain

RackアプリケーションとRackミドルウェア

Rackアプリケーションの中には、レスポンスを返すこと自体を目的とせず、Rackアプリケーションの call メソッドの前後に処理を挟むことを目的として実装される Rackミドルウェア と呼ばれるものがあります。

Rackアプリケーション/Rackミドルウェアと呼ばれるものは両方ともハッシュを引数に call メソッドを呼ぶと所定の形式の配列を返します。そういう意味ではまとめてRackアプリケーションといえますが、両者には以下のような違いがあります。

  • rackupコマンドに与える設定ファイル( config.ru )上で利用を指定するときのDSLが異なる
    • Rackアプリケーションは run Rack::SampleApp, Rackミドルウェアuse Rack::SampleMiddleware で指定
  • Rackミドルウェアには追加の規約があり、1番目の引数に app を受け取る initialize メソッドを定義する 必要がある

Rackミドルウェア(Rackアプリケーション)は自分のコンストラクタに引数として受け取ったアプリケーションに、さらにenvを渡す形で入れ子のように実行していくのですが、最後に実行されるRackアプリケーションを特別に エンドポイント と呼びます。

f:id:woshidan:20181214222517p:plain

参考