前回の
パラメータの操作
(2)
paramsでパラメータの検証
パラメータを検証するにはparams
を、requires
を使います。
次の例では、users
パラメータを必須として定義しています。
raisin.pl
use Types::Standard qw(HashRef Str);
(省略)
params(
requires(
'users',
type => HashRef,
desc => 'User object',
group {
requires(
'name',
type => Str,
desc => 'User Name'
),
optional(
'email', type => Str,
default => undef,
regex => qr/.+\@.+/,
desc => 'User email'
),
}),
);
post sub { ... }
必須ではないパラメータはoptional
で宣言できます。regex
を使うと正規表現で形式を指定できます。
空のJSONをPOSTすると、users
がないためエラーを返却できていることが確認できます。エラーメッセージも自動で返却されます。
$ curl -X POST -H 'Content-Type: application/json' \ http://localhost:5000/users -d '{}' - Invalid Parameters
エラーログにも警告メッセージが自動で表示されます。ステータスコード400
WARN 2021-08-08T04:37:52.787 `users` is required
127.0.0.1 - - [09/Aug/2021:15:10:16 +0900]
"POST /users HTTP/1.1" 400 25 "-" "curl/7.64.1"
include_missingですべてのパラメータの取得
すべてのパラメータを取得するにはinclude_
を使います。デフォルトでは値のないパラメータは取得できないため注意してください。
raisin.pl
(省略)
post sub {
my $all_params = include_missing(shift);
};
route_paramでルートパラメータの取得
ルートパラメータを取得するにはroute_
を使用します。何も指定しない場合はどんな値でも入るため、requires
を使用した強制オプションの定義を推奨します。
raisin.pl
(省略)
use HTTP::Status qw(:constants);
my %USERS = (
1 => {
name => 'Sample Taro',
email => '[email protected]',
},
2 => {
name => 'Sample Jiro',
email => '[email protected]',
},
);
(省略)
params requires(
'id',
type => Int,
desc => 'User ID'
);
route_param 'id' => sub {
get sub {
my $params = shift;
$USERS{ $params->{id} };
};
del sub {
my $params = shift;
delete $USERS{ $params->{id} };
res->status(HTTP_NO_CONTENT);
undef;
};
}
実行タイミングの操作
任意のタイミングで処理を実行するにはhooks
を使います。実行される順番から、before
、before_
、after_
、after
の4種が存在します。
beforeでAPIの実行前に処理実行
APIの実行前に処理を実行したい場合はbefore
、before_
を使います。before
のあとにbefore_
が実行されます。実行タイミング以外の違いはありません。
次の例では、Raisin::Logger
を使って、
raisin.pl
(省略)
plugin 'Logger', fallback => 1;
before sub {
my $self = shift;
app->log( debug => $self->req->method . "\t" .
$self->req->path );
};
APIを実行すると、
DEBUG 2021-08-08T04:15:21.976 GET /users/1
afterでAPIの実行後に処理実行
APIの実行後に処理を実行したい場合はafter
、after_
を使います。after_
のあとにafter
が実行されます。実行タイミング以外の違いはありません。before
とは違ってAPIが正常終了しないと呼び出されない点に注意してください。
次の例では、
raisin.pl
(省略)
after sub {
app->log( debug => "Success" );
};
存在しないエンドポイントを指定してAPIが正常に終了しなかった場合は、
DEBUG 2021-08-19T07:13:35.629 GET /not_exist_path 127.0.0.1 - - [19/Aug/2021:07:13:35 +0900] "GET /not_exi st_path HTTP/1.1" 404 2 "-" "curl/7.64.1"
便利モジュール
本節では、
Raisin::Plugin::SwaggerでAPIドキュメントの作成
HTML形式でドキュメントを生成できるSwagger UIのためのJSONを生成するには、Raisin::Plugin::Swagger
を使います。生成されたJSONをSwagger UIで読み込むと、
使用するには、
plugin 'Swagger';
/swagger.
にアクセスすると、

Plack::TestでAPIのテストの実施
RaisinはPlackに準拠しているため、Plack::Test
モジュールでテストを行えます。
先ほどのAPIのテストの例を記述します。
test.pl
use Test::More;
use Plack::Test;
use HTTP::Request::Common;
use Plack::Loader;
use Plack::Util();
use JSON qw/decode_json/;
my $app = Plack::Util::load_psgi('./raisin.pl');
test_psgi $app, sub {
my $cb = shift;
my $req = HTTP::Request->new(GET => '/users/1');
my $res = $cb->($req);
my $json_data = decode_json($res->content);
is $res->code, 200;
is $json_data->{name}, 'Hoge';
};
done_testing;
レスポンスコードのチェックとJSONの文字列をチェックします。
$ perl test.psgi ok 1 not ok 2 # Failed test at test.psgi line 19. # got: 'Sample Taro' # expected: 'Hoge' 1..2 # Looks like you failed 1 test of 2.
失敗したテストでは、
まとめ
本稿では、
本稿で紹介したものは一部にすぎません。セッション管理や、Moose
と組み合わせると型制約の使用もできます。みなさんも、
さて、
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現! - 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう - 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、 NFT