3

I'm creating a json web service using Mojolicious Lite.

By default Mojolicious returns a HTML response for a server error or not found error.

Is there a way to overwrite this to a custom JSON response?

Franco
  • 57
  • 1
  • 6

3 Answers3

4

Here are two approaches:

  1. Use json as the app's default format and use a not_found.*.json.ep template

    use Mojolicious::Lite;
    app->renderer->default_format('json');
    app->start;
    __DATA__
    
    @@ not_found.development.json.ep
    {"not":"found","code":404,"data":{"key1":"value1","key2":[42,19,"value3"]}}
    
  2. Override json payload with a before_render hook.

    use Mojolicious::Lite;
    hook before_render => sub {
        my ($c,$args) = @_;
        if ($args->{template} && $args->{template} eq 'not_found') {
            $args->{json} = { "too bad" => "so sad" };
        }
    };
    app->start;
    
mob
  • 117,087
  • 18
  • 149
  • 283
3

It's been a minute, but in Mojo 9 in a full app I've just been returning JSON and returning the status:

$c->render( json => $json, status => 404 );

But, I also have a catch-all route at the end of my setup:

$self->routes->any('/*')->to( ... );

Note, however, that there are some decisions to make about HTTP codes and application-level messaging. For example, accessing a defined and valid endpoint that returns zero search results could easily return 200 and an empty JSON array. The endpoint was there, the server knew how to handle it, and zero list items can be seen as valid as any other number. See I've been abusing HTTP Status Codes in my APIs for years, for example.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
1

The Rendering guide discusses how to customize these responses.

Grinnz
  • 9,093
  • 11
  • 18