原文[url]http://chneukirchen.org/blog/archive/2007/02/introducing-rack.html[/url]
在web框架实践中我感到痛苦,我发现有许多本质上做相同事情的重复代码。
而每一个ruby web框架开发者还在不断的开发出他需要的web服务程序。
但愿,框架使用者为他们的选择感到满意。
然而,从本质上说,处理HTTP是很容易的。就是你获得一个请求,返回一个响应。
我们可能这样做这件事:由一个类CGI环境接收一个标准http请求的hash,
返回一个由三部分(状态status,头headers,主体body)组成的响应。
这可以很容易地映射为一个ruby方法调用,如下范例
class HelloWorld
def call(env)
[200, {"Content-Type" => "text/plain"}, ["Hello world!"]]
end
end
你所看到就是一个最简单的Rack应用程序
Rack的目标是提供一个最小的API连接到web servers和web框架
非正式情况下,一个Rack应用程序会调用一个带hash参数的#call方法,
它返回一个由status, headers, body组件的数组。body需要调用#each方法,它一个接一个的返回字符串到body中。
这个给定的hash参数包含一个环境变量的CGI-ish集合和一些特定值,
(env['rack.input'])或者有关运行时环境的信息(例如env['rack.run_once'])
请记住Rack主要是用于框架开发者,通常不暴露给框架使用者,rack刚开始看起来也许有点笨拙,
或者你也许期望更多"优美"的API,但API就应该是简单的(可方便用作lambda)而不是难于接受(暴露的适配器仅仅只有5行代码)
在上面这个最小化API里,有一个库为经常做的事(像query parsing或cookie处理)提供了很多便利(Rack::Requrest和Rack::Response),
愿意的话,你可以免费使用。
但是Rack真正酷的地方在于它提供了一种极其简单的方式组合web应用程序,
毕竟,它仅仅是Ruby对象和它的一个方法的事。而且调用#call不必是一个真实的web server,也可以是另一个程序!
让我向你展示一些已经存在的Rack filters(或者叫中间件):
[list]
[*]Rack::ShowExceptions 捕获所有抛出的异常然后用500-page包装好它们,源自Django(一个python web框架)
[*]Rack::CommonLogger Apache风格的日志
[*]Rack::URLMap 根据path和host跳转到不同的Rack应用程序(一个非常简单的路由)
[/list]
还有另一个工具,Rack::Lint,它检查你的应用程序和filter和其他的filter在一起是否运行良好
如果你的web框架支持Rack,有以下好处:
[list]
[*]提供一个Rack处理器为web servers工作
[*]在没有扩展配置的情况下让多个应用跑在一个web servers上
[*]易于测试(集成和功能测试),从此任何东西可mocked. (Helpers for this are coming soon, too.)
[*]一个很大的不同,从此程序员可以专注于特别的部分上,而停止在烦人的事情上浪费时间。
[*]更多协作特性: 比较 “That upload handler you wrote for IOWA is really great, too bad I use Camping.” 和 “That upload handler you wrote for Rack works great for me too!”
[/list]
Rack由Camping[url]http://code.whytheluckystiff.net/camping/[/url]和ramaze[url]http://ramaze.rubyforge.org/[/url]提供支持
email:
[email protected]
irc:chris2@#ruby-lang on FreeNode
Rack主页[url]http://rack.github.com/[/url]
一个教程[url]http://asciicasts.com/episodes/151-rack-middleware[/url]