Мне нужно объявить маршрут, который мог бы обрабатывать два типа запросов:
GET /api/vote/:value
GET /api/vote/:value/:date
То, как я обрабатываю данные, не сильно отличается в обоих случаях, поэтому я хотел бы, чтобы они определялись в одном и том же месте.
На данный момент я использовал заполнитель подстановочного знака :
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 позволяет достичь /vote/123
и /vote/123/2019-01-13
только в одном объявлении маршрута.
router.get('/vote/:value/:date*?', function(req, res, next) {
// Processing here...
res.json(// etc.);
});
Примечание. Этот пример взят из этого вопроса SO.
Попробовав различные возможности с Mojolicious::Lite
, я обнаружил, что регулярные выражения в маршрутах Mojolicious не нужны, и лучшим решением, которое я нашел, был заполнитель подстановочных знаков. Я что-то упускаю?