REST API with Mojolicious
Buidling an API with Mojolicious is fun. Below is an attempt at a very small REST API that outpus the time in JSON. There are several pieces:
- Mojolicious::LIte App
- App instructions route
- Authentication
- API routes
We start with a Mojolicious::Lite app that uses three routes and an under. The under is a significant piece, because we use that for the authentication. If the proper HTTP BASIC credentials are passed in, then we continue; if not, we get a error in JSON.
After the under, we have a couple routes that comprise our API. The first supports GET and POST, and will will output a string for the current time. The next one outputs an epoch for given the correct GET request.
use Mojolicious::Lite;
use Mojo::Util qw(secure_compare);
# App instructions
get '/' => qw(index);
# Authentication
under(sub {
my $c = shift;
# Have access
return 1 if secure_compare(
$c->req->url->to_abs->userinfo,
'user:523487063f1011e68442002500f18b6d'
);
# Do not have access
$c->render(json =>
{status => "error", data => { message => "Credentials mis-match" }}
);
return undef;
});
# Anything works, a long as it's GET and POST
any ['GET', 'POST'] => '/v1/time' => sub {
shift->render(json => { now => scalar(localtime) });
};
# Just a GET request
get '/v1/epoch' => sub {
shift->render(json => { now => time });
};
# Required
app->start;
__DATA__
@@ index.html.ep
<pre>
Try:
$ curl -v -X GET --user 'user:523487063f1011e68442002500f18b6d' \
http://127.0.0.1:3000/v1/time
$ curl -v -X POST --user 'user:523487063f1011e68442002500f18b6d' \
http://127.0.0.1:3000/v1/time
$ curl -v -X GET --user 'user:523487063f1011e68442002500f18b6d' \
http://127.0.0.1:3000/v1/epoch
$ curl -v -X POST --user 'user:523487063f1011e68442002500f18b6d' \
http://127.0.0.1:3000/v1/epoch
All except the last should work.
</pre>
This code falls short of REST; it is merely a (heavily coupled) HTTP and JSON API.