++ed by:

16 PAUSE users
21 non-PAUSE users.

Stefan G.


Kelp::Response - Format an HTTP response


Examples of how to use this module make a lot more sense when shown inside route definitions. Note that in the below examples $self->res is an instance of Kelp::Response:

    # Render simple text
    sub text {
        my $self = shift;
        $self->res->text->render("It works!");

    # Render advanced HTML
    sub html {
        my $self = shift;
        $self->res->html->render("<h1>It works!</h1>");

    # Render a mysterious JSON structure
    sub json {
        my $self = shift;
        $self->res->json->render({ why => 'no' });

    # Render the stock 404
    sub missing {
        my $self = shift;

    # Render a template
    sub view {
        my $self = shift;
        $self->res->template('view.tt', { name => 'Rick James' } );


The PSGI specification requires that each route returns an array with status code, headers and body. Plack::Response already provides many useful methods that deal with that. This module extends Plack::Response to add the tools we need to write graceful PSGI compliant responses. Some methods return $self, which makes them easy to chain.



Tells if the response has been rendered. This attribute is used internally and unless you know what you're doing, we recommend that you do not use it.


Sets partial response. If this attribute is set to a true value, it will cause finalize to return the HTTP status code and headers, but not the body. This is convenient if you intend to stream your content. In the following example, we set partial to 1 and use finalize to get a writer object for streaming.

    sub stream {
        my $self = shift;
        return sub {
            my $responder = shift;

            # Stream JSON

            # finalize will now return only the status code and headers
            my $writer = $responder->( $self->res->finalize );

            # Stream JSON body using the writer object
            for ( 1 .. 30 ) {
                sleep 1;

            # Close the writer

For more information on how to stream, see the "Delayed-Response-and-Streaming-Body" in PSGI docs.



This method tries to act smart, without being a control freak. It will fill out the blanks, unless they were previously filled out by someone else. Here is what is does:

  • If the response code was not previously set, this method will set it to 200.

  • If no content-type is previously set, render will set is based on the type of the data rendered. If it's a reference, then the content-type will be set to application/json, otherwise it will be set to text/html.

        # Will set the content-type to json
        $res->render( { numbers => [ 1, 2, 3 ] } );
  • Last, the data will be encoded with the charset specified by the app.


Sets the content type of the response and returns $self.

    # Inside a route definition

text, html, json, xml

These methods are shortcuts for set_content_type with the corresponding type. All of them set the content-type header and return $self so they can be chained.

    $self->res->json->render({ word => \1 });


Sets response headers. This is a wrapper around "header" in Plack::Response, which returns $self to allow for chaining.

    $self->res->set_header('X-Something' => 'Value')->text->render("Hello");


A convenience method that sets several response headers instructing most browsers to not cache the response.

    $self->res->no_cache->json->render({ epoch => time });

The above response will contain headers that disable caching.


Set the response code.

    $self->res->set_code(401)->render("Access denied");


Render binary files, such as images, etc. You must explicitly set the content_type before that.

    use Kelp::Less;

    get '/image/:name' => sub {
        my $content = File::Slurp::read_file("$name.jpg");
        res->set_content_type('image/jpeg')->render_binary( $content );


render_error( $code, $error )

Renders the specified return code and an error message. This sub will first look for this error template error/$code, before displaying a plain page with the error text.

    $self->res->render_error(510, "Not Extended");

The above code will look for a template named views/errors/510.tt, and if not found it will render this message:

    510 - Not Extended

A return code of 510 will also be set.


A convenience method that sets code 404 and returns "File Not Found".

    sub some_route {
        if ( not $self->req->param('ok') ) {
            return $self->res->render_404;

If your application's tone is overly friendly or humorous, you will want to create a custom 404 page. The best way to do this is to design your own 404.tt template and put it in the views/error folder.



Renders the stock "500 - Server Error" message. Designing your own 500 page is also possible. All you need to do is add file 500.tt in views/error. Keep in mind that it will only show in deployment. In any other mode, this method will display the optional error, or the stock error message.


This method renders a template. The template should be previously configured by you and included via a module. See Kelp::Module::Template for a template module.

    sub some_route {
        my $self = shift;
        $self->res->template('home.tt', { login => 'user' });