前回の
さまざまなPlack::Middleware
Plack::Middlewareの3パターンについて具体的なモジュールを見ながら理解を深めたところで、
なお、
開発を捗らせるPlack::Middleware
プロダクション環境では必要ありませんが、
DebugLogging──コンソールにデバッグ情報を出力する
Plack::Middleware::DebugLoggingは、
enable "DebugLogging";
たとえば、Content-type: application/
でJSONをリクエストすると、
$ curl -X POST -H "Content-type: application/json" -d '{"user":123}' http://127.0.0.1:5000/?foo=bar
上記のようなリクエストを投げると、
"POST" request for "/" from "127.0.0.1"
Request Headers:
.-----------------+-----------------------------------.
| Header Name | Value |
+-----------------+-----------------------------------+
| Accept | */* |
| Host | 127.0.0.1:5000 |
| Content-Length | 12 |
| Content-Type | application/json |
'-----------------+-----------------------------------'
Query Parameters are:
.-----------------------+-----------------------------.
| Parameter | Value |
+-----------------------+-----------------------------+
| foo | bar |
'-----------------------+-----------------------------'
application/json encoded body parameters are:
{
user => 123
}
StackTrace::LinkedSource──スタックトレースからソースをブラウザで表示する
Plackの開発環境では、
enable "StackTrace::LinkedSource",
lib => ['/your/app/lib', @INC];
![図2 StackTrace::LinkedSourceによるソースコードの表示 図2 StackTrace::LinkedSourceによるソースコードの表示](/assets/images/dev/serial/01/perl-hackers-hub/0041/thumb/TH960_002.png)
ローカルの実行環境ならソースコードを参照するのも難しくないと思いますが、
HTTPヘッダを扱うPlack::Middleware
WebアプリケーションでHTTPヘッダを扱う場面はたくさんあります。そうしたものの中には、
ETag──ETagヘッダを自動で付与する
Plack::Middleware::ETagは、
enable "ETag";
アプリケーションで静的ファイルを配信している場合は、
ConditionalGET──ステータスコード304に対応する
Plack::Middleware::ConditionalGETは、
enable "ConditionalGET";
CrossOrigin──CORSに対応する
Plack::Middleware::CrossOriginは、
enable "CrossOrigin",
origins => '*',
methods => ["GET", "POST"],
max_age => 60*60*24*30;
CORSに対応するヘッダは、
プロダクションに常時投入したいPlack::Middleware
ここでは、
次に紹介する2つのPlack::Middlewareは、
MemoryUsage──メモリの使用量を見る
Plack::Middleware::MemoryUsageは、
enable "MemoryUsage",
callback => sub {
my ($env, $res, $before, $after, $diff) = @_;
my $worst_count = 3;
for my $pkg (sort {
$diff->{$b} <=> $diff->{$a}
} keys %$diff) {
warn sprintf("%-32s %8d = %8d - %8d[KB]\n",
$pkg,
$diff->{$pkg}/1024,
$after->{$pkg}/1024,
$before->{$pkg}/1024,
);
last if --$worst_count <= 0;
}
};
出力内容はcallbackオプションにコードリファレンスを自分で書く必要がありますが、
B::PVOP 0 = 5 - 4[KB]
B::PVIV 0 = 2 - 1[KB]
B::IV 0 = 10 - 10[KB]
IO::Socket::INET 0 = 137 - 137[KB]
Apache2::Status 0 = 18 - 18[KB]
Symbol 0 = 19 - 19[KB]
Profiler::NYTProf──プロファイリングを取得する
Plack::Middleware::Profiler::NYTProfは、
enable "Profiler::NYTProf",
enable_profile => sub { $$ % 2 == 0 },
env_nytprof => 'start=no:addpid=0',
enable_reporting => 0;
prefork型のアプリケーションにおいて、
Plack::Middlewareの利用時のTips
さて、
Plack::Middlewareのロード
Plack::Middlewareのロード方法は2つあります。
1つ目は、
use Plack::Middleware::ETag;
my $app = sub { [ 200, [], ["OK"] ] };
$app = Plack::Middleware::ETag->wrap(
$app,
file_etag => [qw/size/],
);
2つ目は、
use Plack::Builder;
builder {
enable "ETag", file_etag => [qw/size/];
sub { [ 200, [], ["OK"] ] };
};
DSLを使ったロード方法はuseを書く必要がなく、"Plack::Middleware::"
の部分を省略できるなど、
また、plackup
コマンドでも直接使えるので、
$ plackup -e 'enable "ETag"; sub { [200, [], ["OK"]] }'
新しいミドルウェアを試してみる場合などに、plackup
コマンドでさくっと試すというのが簡単でお勧めです。
開発環境とプロダクション環境での切り替え
開発環境とプロダクション環境で利用するPlack::Middlewareを切り替えたい場合は、
use Plack::Builder;
builder {
enable_if {
$ENV{PLACK_ENV} ne "production"
} "DebugLogging";
sub { [ 200, [], ["OK"] ] };
}
ただし、
気になる人は、
if ($ENV{PLACK_ENV} ne "production") {
enable "DebugLogging";
}
実行条件の複雑化への対処
enable_
use Plack::Builder;
use Plack::Builder::Conditionals;
builder {
enable match_if addr(
['192.168.0.0/24', '127.0.0.1']
), "ReverseProxy";
$app;
};
Plack::Middlewareのロード順と実行順序
先述したとおりPlack::Middlewareには、
次の2つのPlack::Middlewareがあるとします。1つ目はPlack::Middleware::Fooで、$self->app
の前後で標準出力にミドルウェア名を出力するだけです。
package Plack::Middleware::Foo;
use parent qw( Plack::Middleware );
sub call {
my ($self, $env) = @_;
say "Before Foo";
my $res = $self->app->($env);
say "After Foo";
return $res;
}
package Plack::Middleware::Bar;
use parent qw( Plack::Middleware );
sub call {
my ($self, $env) = @_;
say "Before Bar";
my $res = $self->app->($env);
say "After Bar";
return $res;
}
この2つのミドルウェアを次のように利用します。Foo➡Barの順にenableしています。
use Plack::Builder;
builder {
enable "Foo";
enable "Bar";
sub { say "App"; [ 200, [], ["OK!"] ] };
};
これを実行すると、
Before Foo
Before Bar
App
After Bar
After Foo
enableしたのはFoo➡Barの順でしたが、$self->app
のあとに書かれたPlack::Middlewareの処理は、
<続きの
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現! - 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう - 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、 NFT