如何在 Mojolicious::Lite 中声明带有可选占位符的路由路径?
How to declare a route path with an optional placeholder in Mojolicious::Lite?
我需要声明一个可以处理两种请求的路由:
GET /api/vote/:value
GET /api/vote/:value/:date
我处理数据的方式在这两种情况下并没有什么不同,所以我希望它们在同一个地方定义。
我现在所做的是我使用了 wilcard placeholder :
use Mojolicious::Lite -signatures;
use DateTime;
get '/vote/*values' => sub ($c) {
my $datetime = DateTime->now;
# Then we process the route parameters
my @params = split('/', $c->param('values'), 2);
# Optional if no date provided in the route
if ( defined $params[1] ) {
my @dates_params = split('-', $params[1], 3);
my %datetime = (
year => $dates_params[0],
month => $dates_params[1],
day => $dates_params[2],
);
$datetime = DateTime->new(%datetime);
}
my %vote = (
value => $params[0],
datetime => $datetime,
);
# ... More code here
$c->render(json => $data);
}
这种方式工作得很好,但我对这个解决方案感觉不太舒服,因为它不是很明确也不是可读的,而且我知道其他框架允许以看起来更令人满意的方式做类似的事情.
例如,以下使用 Express.js routing capabilities,允许仅在一个路由声明中到达 /vote/123
和 /vote/123/2019-01-13
。
router.get('/vote/:value/:date*?', function(req, res, next) {
// Processing here...
res.json(// etc.);
});
注:本例来自this SO question.
在 Mojolicious::Lite
尝试了各种可能性后,我发现 Mojolicious 路由中的正则表达式不是问题,我找到的最佳解决方案是通配符占位符。我错过了什么吗?
% mojo generate lite_app optional
...
% $EDITOR optional
可以通过给它一个默认值 undef
:
来将日期标记为可选
#!/usr/bin/env perl
use Mojolicious::Lite -signatures;
get '/vote/:value/*when' => { when => undef } => sub ($c) {
my $value = $c->stash('value');
my $when = $c->stash('when');
$c->render(
format => 'txt',
text => $value . ' ' . ( defined $when ? $when : 'nope' ) . "\n"
);
};
app->start;
然后允许有或没有日期查询:
% ./optional get /vote/42 2>/dev/null
42 nope
% ./optional get /vote/42/2020/01/07 2>/dev/null
42 2020/01/07
%
我需要声明一个可以处理两种请求的路由:
GET /api/vote/:value
GET /api/vote/:value/:date
我处理数据的方式在这两种情况下并没有什么不同,所以我希望它们在同一个地方定义。
我现在所做的是我使用了 wilcard placeholder :
use Mojolicious::Lite -signatures;
use DateTime;
get '/vote/*values' => sub ($c) {
my $datetime = DateTime->now;
# Then we process the route parameters
my @params = split('/', $c->param('values'), 2);
# Optional if no date provided in the route
if ( defined $params[1] ) {
my @dates_params = split('-', $params[1], 3);
my %datetime = (
year => $dates_params[0],
month => $dates_params[1],
day => $dates_params[2],
);
$datetime = DateTime->new(%datetime);
}
my %vote = (
value => $params[0],
datetime => $datetime,
);
# ... More code here
$c->render(json => $data);
}
这种方式工作得很好,但我对这个解决方案感觉不太舒服,因为它不是很明确也不是可读的,而且我知道其他框架允许以看起来更令人满意的方式做类似的事情.
例如,以下使用 Express.js routing capabilities,允许仅在一个路由声明中到达 /vote/123
和 /vote/123/2019-01-13
。
router.get('/vote/:value/:date*?', function(req, res, next) {
// Processing here...
res.json(// etc.);
});
注:本例来自this SO question.
在 Mojolicious::Lite
尝试了各种可能性后,我发现 Mojolicious 路由中的正则表达式不是问题,我找到的最佳解决方案是通配符占位符。我错过了什么吗?
% mojo generate lite_app optional
...
% $EDITOR optional
可以通过给它一个默认值 undef
:
#!/usr/bin/env perl
use Mojolicious::Lite -signatures;
get '/vote/:value/*when' => { when => undef } => sub ($c) {
my $value = $c->stash('value');
my $when = $c->stash('when');
$c->render(
format => 'txt',
text => $value . ' ' . ( defined $when ? $when : 'nope' ) . "\n"
);
};
app->start;
然后允许有或没有日期查询:
% ./optional get /vote/42 2>/dev/null
42 nope
% ./optional get /vote/42/2020/01/07 2>/dev/null
42 2020/01/07
%