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:
$self->res
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; $self->res->render_404; } # 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.
Plack::Response
$self
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.
finalize
partial
writer
sub stream { my $self = shift; return sub { my $responder = shift; # Stream JSON $self->res->set_code(200)->json->partial(1); # 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 ) { $writer->write(qq|{"id":$_}\n|); sleep 1; } # Close the writer $writer->close; }; }
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.
render
application/json
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 $self->res->set_content_type('image/png');
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.
set_content_type
$self->res->text->render("word"); $self->res->html->render("<p>word</p>"); $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");
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 subclass this module into your own class, for example MyApp::Response. Then override the render_404 method.
MyApp::Response
render_404
package MyApp::Response; use parent 'Kelp::Response'; sub render_404 { my $self = shift; $self->set_code(404)->template('errors/404.tt'); }
You'll have to override the "response" in Kelp method in your main module too, in order to instruct it to use your new class:
package MyApp; use parent 'Kelp'; sub response { my $self = shift; return MyApp::Response->new( app => $self ); }
Renders the stock "500 - Server Error" message. See "render_404" for examples on how to customize it.
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' }); }
To install Kelp, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Kelp
CPAN shell
perl -MCPAN -e shell install Kelp
For more information on module installation, please visit the detailed CPAN module installation guide.