Tatsumakiを触ってみたいなあと思ったらなんかPSGI/Plackの迷路に入ってしまい、つぶやいてたらid:miyagawaさんが色々教えて下さったので、せっかくなのでまとめておきます。
教えてもらってない自分で調べたことも書いてるので、間違ってたらごめんなさい!
PSGIとは
WEBアプリとWEBサーバ間の仕様です。仕様はここ。WSGIやRackのPerl版です。レガシーな分け方で言えば、CGI(or mod_perl or FastCGI)の仕様の層になります。
Plackとは
PSGIの仕様に関するリファレンス実装群です。
- Plack(特にPlack::Server)
- Plack::Request(と、Plack::Response)
PlackとPlack::Requestは、互いに依存しません(Plack-Request-0.05からそうなってます)。レガシーな例えをすれば、ApacheとCGI.pmが依存してないのと同じです(どちらも、CGIの仕様に沿ってるだけ)。
なお、PSGIとPlackの説明で気がつくと思いますが、これらは低レベルの層*2に位置しており、CatalystのようなWAFの層ではありません。WAFはこれらの上の層で構築されます。
てっとり早く試したい
1. Plackをインストール
2. app.psgiという名前のファイルを用意
use strict; use warnings; sub { my $env = shift; return [ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ] ]; };
3. app.psgiのあるディレクトリでplackup を実行
4. ブラウザで http://localhost:5000/ を開く
大事なのは、 app.psgiはPSGIの仕様に沿って書かれたアプリなので、PlackじゃなくてもPSGIに対応したサーバさえあれば動くってことです*3。
PSGI仕様におけるMiddlewareとは
PSGIアプリケーションに機能を付け加えて、新たなPSGIアプリケーションを作る物です。例えば、以下のような物。
package XHeader; use strict; use warnings; use base Exporter::; our @EXPORT = qw/xheader/; # xheader is a middleware to wrap $app sub xheader { my $app = shift; sub { my $env = shift; my $res = $app->($env); push @{$res->[1]}, 'X-PSGI-Used' => 1; return $res; }; }
これは例えば、以下のように適用します。
# app.psgi use strict; use warnings; use XHeader; # apply the middleware to a simple PSGI application xheader sub { my $env = shift; return [ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ] ]; };
ただし、この適用法に関しては、(少なくとも現状では)PSGIの仕様の中では決められていません。Middlewareはクラスの形をとることもできますし、もっと別の形になっているかもしれません。
PlackにおけるMiddleware
Plackでは、Plack::Middlewareというベースクラスを提供しており、 Middleware の開発を容易にしてます。
Plack::Middleware に沿って Middleware を作ると、Plack::Builderの恩恵を受けて、DSL的にMiddlewareを適用することができます。
なお、現状ではPlack::Builderの提供するDSLは以下のようにサブルーチンの形のMiddlewareも適用できますが、ドキュメントにないのでなくなるかもとのことです。
# !!CAUTION!! サブルーチンへのenableはドキュメントにない。 # そのうちサポートされなくなるかも。 # app.psgi use strict; use warnings; use XHeader; use Plack::Builder; builder { enable \&xheader; sub { my $env = shift; return [ '200', [ 'Content-Type' => 'text/plain' ], [ "Hello World" ] ]; }; };
><
*1:【2009-11-02 追記】他にCGI::PSGIと言うのもあり、こちらはCGI.pmと同じインタフェースを提供します。Plack::RequestはHTTP::Engine::RequestやCatalyst::Requestに近いインタフェースです。
*2:何も使わなければ、それこそ素のCGIで開発しているようなもんです(ある程度Middlewareは入ってますが)。Plack::Requestを使ってもCGI.pm的な時代にまでしかなりません。
*3:もうちょっと言えば、Plack::Request を使ってapp.psgiを使っても同じことが言えます。Plack::Server以外のPSGIに対応しているサーバで動かせます。