Rack的用法,以及rails的启动加载顺序 - tianlu1677/tianlu1677.github.io GitHub Wiki
1. 什么是rack
Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.
2. 启动方式
2.1 必须要满足这三个条件,才可以启动一个服务
- The HTTP response code
- A Hash of headers
- The response body, which must respond to
each
可以有这两种写法:
# my_rack_app.rb
require 'rack'
app = Proc.new do |env|
['200', {'Content-Type' => 'text/html'}, ['A barebones rack app.']]
end
Rack::Handler::WEBrick.run app
或者使用 rackup 命令
# config.ru
run Proc.new { |env| ['200', {'Content-Type' => 'text/html'}, ['get rack\'d']] }
$ rackup config.ru ## 这里的 rackup就是只是启动而已
require "rack"
Rack::Server.start
3.Rack 的模块 Rack::Builder
它会将rack application 以及 middlewares 封装成一个 单独的rack application。这样就可以单独调用了。
3.1 Rack::Builder#run
infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, [env.inspect]]}
Rack::Handler::WEBrick.run infinity, :Port => 9292
||
infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, [env.inspect] ]}
builder = Rack::Builder.new
builder.run infinity
Rack::Handler::WEBrick.run builder, :Port => 9292
|| 这种把内容方法block里面
infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, [env.inspect] ]}
builder = Rack::Builder.new do
run infinity
end
Rack::Handler::WEBrick.run builder, :Port => 9292
3.2 Rack::Builder#use
这use是用于把中间件加载到当前的rack application中。
infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, [env.inspect] ]}
builder = Rack::Builder.new do
use Rack::CommonLogger
run infinity
end
Rack::Handler::WEBrick.run builder, :Port => 9292
3.3 Rack::Builder#map
Rack::Builder#map mounts a stack of rack application/middlewares the specified path or URI and all the children paths under it. 挂载不同的URL或者中间件的路径。
infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, env.inspect]}
builder = Rack::Builder.new do
use Rack::CommonLogger
map '/' do
run infinity
end
map '/version' do
run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["infinity 0.1"] ] }
end
end
Rack::Handler::WEBrick.run builder, :Port => 9292
或者采用嵌套的形式
infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, env.inspect]}
builder = Rack::Builder.new do
use Rack::CommonLogger
map '/' do
run infinity
end
map '/version' do
run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["infinity 0.1"] ] }
end
map '/version/last' do
run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["infinity beta 0.0"] ] }
end
end
Rack::Handler::WEBrick.run builder, :Port => 9292
而一般会封装在一个 .ru文件中,所有相关的配置。不会采用Rake::Builder,而用rackup这个命令。
rackup infinity.ru
# infinity.ru
infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, env.inspect]}
use Rack::CommonLogger
map '/' do
run infinity
end
map '/version' do
map '/' do
run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["infinity 0.1"]] }
end
end
end
或者是这样
config_file = File.read(config)
rack_application = eval("Rack::Builder.new { #{config_file} }")
And then rackup supplies rack_application to the respective webserver :
server.run rack_application, options
4.rails 启动顺序
TODO 解构
参考: