The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Flea - Minimalistic sugar for your Plack


version 0.04


    # app.psgi, perhaps?
    use Flea;

    my $app = bite {
        get '^/$' {
            file 'index.html';
        get '^/api$' {
            json { foo => 'bar' };
        post '^/resource/(\d+)$' {
            my $request  = request(shift);
            my $id       = shift;
            http 400 unless valid_id($id);
            my $response = response($request)


PSGI/Plack is where it's at. Dancer's routing syntax is really cool, but it does a lot of things I don't usually want. What I really want is Dancer-like sugar as an extremely thin layer over my teeth^H^H^H^H^H PSGI apps.

What's with the name?

With all the bad tooth decay jokes, why not call it Gingivitis or something? That's too much typing. And it sounds gross. Also, fleas are small and they bite you when you're not paying attention. You have been warned.


Flea is a Exporter::Declare. Everything from there should work.


Takes a block as an argument and returns a PSGI app. Inside the block is where you define your route handlers. If you try defining them outside of a route block, Flea will bite you. Note that the routing is done via path_info, so your app will be mountable via Plack::Builder.

get, post, put, del, any

any will match any request method, and the others will only match the corresponding method. If you need to match some other method or combination of methods, see "method". Aren't you glad you can rename these? (see Exporter::Declare).

Next come a regex to match path_info against. You should surround the regex with single quotes. LISTEN: are you listening? SINGLE QUOTES. This isn't a real perl string, it's parsed with Devel::Declare magic (you'll end up with a compiled regex). If you try to use qr or something cute like that, you'll get bitten. If you need to do something fancy, use "route" instead of these sugary things.

Last of all comes a block. This receives the PSGI env as its first argument and any matches from the regex as extra arguments. It can return either a raw PSGI response or something with a finalize() method that returns a PSGI response (like Plack::Response).


Just like get/post/etc, except you can tack on method names (separated by spaces) to say which methods will match.

    method options '^/regex$' {

    method options head '^/regex$' {

route($methods, $regex, $sub)

This is an honest to goodness real perl subroutine, unlike the magic bits above. You call it like:

    route ['get', 'head'], qr{^a/real/regex/please$}, sub {

Yes, $methods has to be an arrayref. No, $regex doesn't have to be compiled, you can pass it a string if you want. But then, why are you using route? Yes, you need the semicolon at the end.


Short for Plack::Request->new($env)


Short for $request->new_response(200).

uri($request, $path)

Returns a canonical URI representing the path you passed with $request->base welded onto the front. Does the Right Thing if $request->base or $path have leading/trailing slashes. Handy for links which are internal to your app, because it will still behave if you mount your app somewhere other than /.


Returns a full 200 OK, content-type application/json; charset=UTF-8 response. Pass it something that JSON::encode_json can turn into a string.


text/plain; charset=UTF-8.


text/html; charset=UTF-8. Seeing a pattern?

file($filename, $mime_type?)

Dump the contents of the file you named. If you don't give a mime type, text/html is assumed.

handle($fh, $mime_type?)

Much like file, except you pass an open filehandle instead of a filename.

http($code, @args)

Shortcut for HTTP::Exception->throw. Accepts the same arguments.


Throws a Flea::Pass exception, which causes Flea to pretend that your handler didn't match and keep trying other handlers. By the way, the default action when no handler is found (or they all passed) is to throw a 404 exception.


This module is extremely immature as of this writing. Not only does the author have the mind of a child, he has never before tinkered with Devel::Declare magic, although Exporter::Declare sure does help. The author hasn't thought very hard about the interface, either, so that could change. When Flea breaks or doesn't do what you want, fork it on "GITHUB" and/or send the author a patch or something. Or go use a real web framework for grownups, like Catalyst.


Oh yeah, Flea is hosted on Github at


You can try hopping into #flea on The author might even be there. He might even be paying attention to his irc client!


PSGI, Plack, Dancer, Exporter::Declare