取势 明道 优术

作者为 扶 凯 发表

中间件是 PSGI 中的一个概念(也是来源于 Python 中的 WSGI 和 Ruby 中的 Rack ).在这里我们定义的组件是工作在 Web 服务器和应用程序的中间的.

这个图非常好的指出来 中间件(middleware ) 的概念.在 PSGI 的应用在这个洋葱中的最核心的一层.中间件的组件是会取得源应用的返回内容,他们会在接收到请求时做一些预处理(由外向内),然后进行后面的处理 response 进行输出 (内到外).
很多的功能都可以被添加到 PSGI 应用和中间件组件中,象HTTP身份验证,捕获错误日志的输出或 JSON 的输出.

Plack::Middleware

Plack::Middleware 是一个中间件组件的中的基类,它允许您通过它就能非常容易的编写的中间件,也有非常好的可重用性.
通过 Plack::Middleware 来写中间件组件非常容易.只要给源应用使用 wrap 的方法来包起来就行了.

my $app = sub { [ 200, ... ] };

use Plack::Middleware::StackTrace;
$app = Plack::Middleware::StackTrace->wrap($app);

这个例子,通过 StackTrace 的中间件使用 wrap 的方法包了一个源应用(如果默认是使用 plackup 启动的话,这个应用其实是启动的),如果包住的这个应用有 error 的信息的话,这个中间件会抓到这些信息,通过 Devel::StackTrace::AsHTML 模块显示成 HTML 的网页.
一些其它的中间件可以指定一些参数.象下面的例子中,你能在 $app 后面加一个 hash 做为参数传进去.象下面一样

my $app = sub { ... };

use Plack::Middleware::MethodOverride;
$app = Plack::Middleware::MethodOverride->wrap($app, header => 'X-Method');

安装了多个中间件组件后,当你必须使用多个这组件模块时,非常麻烦.要象上面一样写很多次.有个快速的解决方法,就是使用 DSL 风格的语法:

use Plack::Builder;
my $app = sub { ... };

builder {
    enable "StackTrace";
    enable "MethodOverride", header => 'X-Method';
    enable "Deflater";
    $app;
};

大约在下一个文章,你可以看到 Plack::Builder 的详细介绍.

 

中间件和框架

中间件的最大的优点在于它可以封装任何 PSGI 应用.它可能无法从代码示例明显的看出来,但上面使用 warp 的方法,可用来来包含任何应用程序,这意味着你可以运行在支持 PSGI 的任何 WEB 应用中使用中间件组件.举例来说看 CGI::Application:

use CGI::Application::PSGI;
use WebApp;

my $app = sub {
    my $env = shift;
    my $app = WebApp->new({ QUERY => CGI::PSGI->new($env) });
    CGI::Application::PSGI->run($app);
};

use Plack::Builder;
builder {
    enable "Auth::Basic", authenticator => sub { $_[1] eq 'foobar' };
    $app;
};

在使用 CGI::Application 的应用的时候,这会打开基本的认证用的中间件 Auth::Basic.你能使用这种方法,用在任何支持 PSGI 的框架上.

这是译文,原文地址:http://advent.plackperl.org/2009/12/day-10-using-plack-middleware.html

 

来了就留个评论吧! 2个评论



    fans 2011年06月26日 的 08:02

    这不是tor的图么。。