RailsはRackというものを使ってサーバープログラムからHTTP通信を行ないます。
https://github.com/rack/rack/blob/master/SPEC.rdoc
Rackとは
rubyでwebアプリケーションを作る時、アプリケーションとサーバーの受け渡しを決めた仕様の事です。
https://github.com/rack/rack
gemで入れられるrackはサーバーを立ち上げるためのコマンド、Rubyで作られた有名なwebサーバーで使えるようにするためのアダプタ。圧縮、クッキー、ベーシック認証といった基本的な機能が入っています。
最小限のRackアプリケーション
runメソッドで呼ばれるオブジェクトはcallメソッドを持っていれば良いので、lambdaではなく、classにしてもいいです。
run ->(env){ [200, {"Content-Type" => 'text/html'}, ['<html><body><p>it works!</p></body></html>']] }
引数がリクエスト、ハッシュです。例を上げると
- env['QUERY_STRING'] 文字通りURLの?以降のクエリストリングです
- env['rack.input'] リクエストbodyですPOSTの時使うアレです、stringではなくIOオブジェクトです
- env['PATH_INFO'] 文字通りURLのパスです、localhost:3000/usersの/usersです
- env['HTTP_(任意の名前)'] リクエストHTTPヘッダがここに入りますHTTP_の後NAMEが入り中身がVALUEです
戻り値はArrayです
- 0番目がステータスコード
- 1番目がレスポンスヘッダ
- 2番目がレスポンスbody
細かい仕様は公式に載ってます
https://github.com/rack/rack/blob/master/SPEC.rdoc
source 'https://rubygems.org'
gem 'rack'
~/projects/rackzikken $bundle install
~/projects/rackzikken $ls
Gemfile Gemfile.lock config.ru
~/projects/rackzikken $rackup
[2020-06-22 17:51:50] INFO WEBrick 1.4.2
[2020-06-22 17:51:50] INFO ruby 2.5.0 (2017-12-25) [x86_64-darwin16]
[2020-06-22 17:51:50] INFO WEBrick::HTTPServer#start: pid=8479 port=9292
bundle installしてあげた後、rackupコマンドを打てばwebrick(webサーバー)が立ち上がります。
$curl localhost:9292
<html><body><p>it works!</p></body></html>
適当なブラウザでアクセスすればレスポンスが帰ってきます。
rackミドルウェア
rackサーバーとrackアプリケーションの間に入って引数のenvを加工したり、アプリケーションから帰ってきたレスポンスを加工する事ができます。
gemで入れられるrackコマンドには、さっきの圧縮、クッキー、ベーシック認証などがrackミドルウェアの形で入っています。
コンストラクタにRackアプリケーションが入ってきて、サーバー側からcallが呼ばれるので、rackアプリケーションのcallを呼んであげて、帰ってきたレスポンスを加工します。
callメソッドの引数、戻り値はrackアプリケーションの時と同じです。
config.ruのuseメソッドにミドルウェアのクラスを渡してあげると使えるようになります。
rackサーバー -> rackミドルウェア -> rackミドルウェア -> .... -> rackアプリケーションのようにつみ重ねていく事ができます。
class MyRackMiddleWare
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
[status, headers, ["middleware\n"] +body]
end
end
use MyRackMiddleWare
run ->(env){ [200, {"Content-Type" => 'text/html'}, ['<html><body><p>it works!</p></body></html>']] }
bodyが加工されました
$curl localhost:9292
middleware
<html><body><p>it works!</p></body></html>
まとめ
- railsはrackアプリケーション
- rackはサーバーとアプリケーションのやりとりの仕様
- rackミドルウェアをつみかさねて基本的な機能を使い回せる。