LoginSignup
0
0

More than 3 years have passed since last update.

Railsはどうやってサーバーとつながるのか(rackの話)

Last updated at Posted at 2020-07-10

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にしてもいいです。

config.ru
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

Gemfile
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アプリケーションのようにつみ重ねていく事ができます。

config.ru
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ミドルウェアをつみかさねて基本的な機能を使い回せる。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0