Ruby on Rack #1 - 与Rack的第一次亲密接触
http://article.yeeyan.org/view/52654/18184
Rack提供了Web服务器和Ruby开发框架之间的接口。它将框架编写者从为每个Web服务器单独编写一个处理模块的繁重负担中解脱出来,可以节省大量重复劳动。
Ruby社区几乎每个星期都会有新的框架出现,但是这些框架里面,Rack 并没有得到足够的关注。它应该被关注。同时,为了全面利用Rack, 在下一个 Rails 稳定版本2.2 之后会有一个更好的公共接口。
Rack 最初的灵感来自于Python的 wsgi ,并且由于它的简单性和准确性,很快在Ruby社区成为了一个实际的web应用/服务器接口。你可能想看看来自于Rack之父-Christian Neukirchen 的Rack介绍。
Rack是什么 ?
实际上,你可以把"Rack"分成两部分:
Rack 规则
Rack规则指定一个Rack应用和webserver应该如何精确的交互:
这只是个简要的说明,你可以在这里看到更详细的内容。
严格的讲,为了写一个Rack ready application你不需要这个rack gem。这样做仅仅是为了规范:
Rack Gem
Rack gem 是一个公共类和辅助类的集合,它可以使每一个Rack app开发者更轻松。它包括了基本的request, response, cookies 以及sessions的实现. 还有相当多有用的中间件。总之,安装rack gem,你只需要这样:
$ sudo gem install rack
总结
- Rack 是一个支持你自己Ruby框架的框架.
- Rack 提供一个不同web服务器和你的框架/应用之间的接口。使它可以更容易的让你的框架/应用对任意支持Rack的web服务器兼容– Phusion Passenger, Litespeed, Mongrel, Thin, Ebb, Webrick 仅举几例.
- Rack消减你的成本.你可以免费的得到request, response, cookies, params 以及sessions .
- 没有类冲突使得在用一应用使用多个框架成为可能。 Rails 和 sinatra 集成 是个很好的例子。
- 中间件 ! 想一想Rails的 before_filter/after_filter 可以在支持Rack的不同框架重复使用。例如,在你的Rails应用,Sinatra应用和你自定制的Rack应用里都可以使用同一个Anti-spamming rack中间件。
例子
让我们使用mongrel,从一个可能是最小的rack应用例子来开始。
1 |
require 'rubygems' |
上面的代码传一个HelloWorld对象到mongrel的rack处理器,指定了9292端口。
The HelloWorld object遵循了rack规范 :
- call方法仅带一个env参数
- call() 方法返回一个数组,包含这三个值 [http_status_code, response_headers_hash, body]
这就够了! 运行脚本,然后浏览器里输入http://localhost:9292, 你就会看到这个耀眼的 “Hello Rack!” 信息。
等等,既然是一个响应call()的ruby过程,为什么不用一个proc来代替呢? 那么,没有理由不这么做:
1 |
require 'rubygems |
另一种常见的模式是用method(:something), 这会返回一个 Method class 对象:
1 |
require 'rubygems' |
带走你巨慢的“Hello World”表演吧,你不可能再写个比这更快的"Hello World" ruby 应用了。
Rack it up’
如我之前所说,rack gem为rack app开发者带来一大堆有用的东西。 rackup 就是其中之一.在前一个例子里,我直接用了mongrel处理器Rack::Handler::Mongrel ,甚至还有硬编码的端口号。用rackup,这些事情都变得可配置。! 但是用rackup,你需要用一个rackup配置文件来支持它。对于上一个例子,配置文件有点像:
1 |
# config.ru |
只需要一行,按照约定,你应该使用.ru作为一个rackup配置文件的扩展名。支持它运行一个RackObject 你需要:
$ rackup config.ru
但是默认的,rackup会在9292端口启动一个服务。但是你可以通过一个-p参数来指定这个端口号。你可以看更多的帮助:
$ rackup --help