RubyでオレオレWebフレームワークを作っているのですが、だいぶ形になってきたので知識の整理がてら色々まとめてみる✍
今回のゴール
最終的には、CRUDが動くようなアプリケーションを作れるような感じになるはずですが、
今回は下記のような実装でlocalhost:8080
にアクセスした際にHello World
がブラウザに表示出来るようなところまでを整理します🌏
まず最初の構成は下記のような形です、シンプル🐥
処理の流れはこんな感じです。
ruby app.rb
でWEBrickが起動- ブラウザでアクセスした際にrequestをWEBrickへ送信
- WEBrickへのrequestをenvとしてRackを経由してapplicationへ渡す
- applicationがresponse生成してRackを経由してWEBrickへ渡す
- WEBrickがresponseをブラウザに返却
Rackを使ってWEBrickとコードを繋ぐ 🤝
rubyのコードからWEBrickを起動するためにはRackを使います📦
Rackは、様々なWebServerへのシンプルなインターフェースを提供してくれるgemです💎
下記のルールを守ればRackを使って各種WebServerとやりとりすることが出来ます。
Rack applications A Rack application is a Ruby object (not a class) that responds to call. It takes exactly one argument, the environment and returns an Array of exactly three values: The status, the headers, and the body. https://www.rubydoc.info/github/rack/rack/master/file/SPEC
簡単に説明すると下記のような感じです。
call
メソッドが定義されていること- 環境(リクエスト)を受け取る引数を一つとること
- status、header、bodyの配列を返却すること
なので下記のようなprocオブジェクトもRackのルールを満たしており、WebServerとやりとりすることが出来ます、Rackすごい🙌
Proc.new { |env| ['200', {'Content-Type' => 'text/html'}, ["Hello World"]] }
WEBrickとRackを使ってレスポンスを返す🤟
それでは実際にruby app.rb
でWEBrick
を起動し、Rackを使ってレスポンスHello World
を返却するコードを見ていきましょう👀
require 'rack' class Application def run! # Rackのルールに沿ったレスポンスを返却するコード app = Proc.new { |env| ['200', {'Content-Type' => 'text/html'}, ["Hello World"]] } # 上記コードを乗せてWEBrickを起動 Rack::Handler::WEBrick.run app end end # ruby app.rbの処理が終了したらApplication.run!を実行する at_exit { Application.new.run! }
先程説明したRackのルールを守ったProcオブジェクトを作成して、変数app
に格納します。
そしてRack::Handler::WEBrick.run
でRackを使ってWEBrickを起動します。このとき引数にapp
を渡すことで、リクエスト時にapp
に入れたProcオブジェクトが実行され、結果がレスポンスとして返却されます。
at_exit
で起動用のメソッドを実行することでruby app.rb
が終了したらWEBrickが定義したコードが乗った状態で起動します🤖
実際の実行結果が下記の通りです。
$ ruby app.rb [2019-08-25 18:02:05] INFO WEBrick 1.4.2 [2019-08-25 18:02:05] INFO ruby 2.6.3 (2019-04-16) [x86_64-darwin18] [2019-08-25 18:02:05] INFO WEBrick::HTTPServer#start: pid=40353 port=8080
localhost::8080
にアクセスするとHello World
が表示されます 🙌
おわりに
今回はRackを使ってWEBrickを起動し、Hello Worldをレスポンスとして返すところまでの実装を整理してみました✍
シンプルなルールに沿っていれば簡単に様々なWebServerとやりとり出来るRackという仕組みは分かりやすいし、とても便利ですね💎
次回はHTTP METHOD/URLと実行するロジックを紐付けるroutingの仕組みを整理していこうかなと思っています🛣