Rails serverの挙動を理解するためのActionDispatch


ActionDispatchの挙動についてあんま理解してなかったので
routes.rbみたいなのだけ自分で作って、サーバー起動させるスクリプトを書いて見ました。
とは言いつつ、ただの基本で

ActionDispatchは
RoR中の

- Railties
- ActionPack
    - **ActionDispatch**
    - ActionController
    - AbstractController
- ActiveModel
- ActiveRecord
- ActionView
- ActiveSupport
- ActionMailer

ActionPackの一部であり、
ルーティングのためのDSLとも言えるし、Rackミドルウェアとも言える
Rails アプリケーションがあれば consoleで確認してみればいいと思うのだけれども


> Rails.application.class
=> YOURAPPLICATION::Application

> Rails.application.app
 @app=
    #<ActionDispatch:: .....
あった!! ミドルウェアそうにある

> Rails.application.middleware
=> #<ActionDispatch::MiddlewareStack....
色々ある

> Rails.application.endpoint
=> #<ActionDispatch....
> Rails.application.routes
=> #<ActionDispatch::Routing::RouteSet...

よくよく調べると、HTTPやらjourney, middleware, Request, Routingなどなどあった
また、

- rake routesの出力は ActionDispatch::Routing::RoutesInspector
- config/routes.rbで使ったり、最終的に呼び出すメソッドが生えてるのが ActionDispatch::Routing::Mapper
- ルーティングがマッチするとコントローラに処理を渡したり、drawメソッドを提供してくれる ActionDispatch::Routing::RouteSet

だったりと、それぞれ分かれていて、内容が深かった。

結果的に ruby routes.rbでサーバーを立てて 3001 portで起動できるサーバーを書いたのでそちらのソースは以下
最後のRack::Handler.defaultなどはrackを理解しないと読み解けないと思うので、時間があればRackミドルウェアのcallまで
run Hoge.new からどうやってたどり着くのかというのをやって見るのも面白いかもしれない。

routes.rb

require 'action_dispatch'
header = { 'Content-Type' => 'text/html' }
routes = ActionDispatch::Routing::RouteSet.new
routes.draw do
  get 'hoge', to: -> env{ [200, header, ['hoge']] }
  get 'fugafuga', to: -> env{ [200, header, ['fugafuga']] }
  root to: -> env{ [200, header, ['Hello World!!']] }
end
Rack::Handler.default.run routes, Port: 3001

おまけ

Railsの routes.rbで非常にroutingが増えて来たら、

conifig/Initializers/routing_draw.rbに

class ActionDispatch::Routing::Mapper
  def draw(routes_name)
    instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb")))
  end
end
Rails.application.routes.draw do
  resources :...
  resources :...
  resources :...
  resources :...
  resources :...

  draw :user
end

こうすると、config/routes/user.rbを探しに行き、そこに書いてあるroutingの記述をroutes.rbにマッピングしてくれるので、
routingが読みやすく追加しやすくなる。即出でそこまで新しくないが、大きな開発には必須かなと。
Rails 4がではじめたときは実装されていたが、その後removeされた跡があるので見ておくといいかもです。
https://github.com/rails/rails/commit/5e7d6bba79393de0279917f93b82f3b7b176f4b5

以上です。