2012 Feed

OX::Request and OX::Response

OX - 2012-12-08

OX::Request

As mentioned previously, action subroutines and methods receive an OX::Request instance containing the request data as their first argument. OX::Request provides access to all of the request data that the application received for the current request. Everything from the PSGI environment is available in a nicely packaged object, as well as details of how OX matched the request against your router. There are even shortcuts to build OX::Response objects for your convenience.

Basic request data

The OX::Request instance provides methods to access all of the various parts of the request. Some commonly used methods include:

  • $r->path

    Returns the request path.

  • $r->method

    Returns the HTTP method (GET, POST, etc) that was used for the request.

  • $r->headers

    Returns an HTTP::Headers object containing the headers in the request.

  • $r->param($name), $r->parameters

    Allows access to the request parameters, either from the the query string or from the request body. The param method returns the value for a single parameter, while the parameters method returns a hashref of all parameters given.

  • $r->uploads

    Returns a hashref of upload objects, which can be used to access uploaded files.

OX::Request is a subclass of Web::Request, so you can find more details in its documentation.

Encoding

By default, OX decodes all request data as UTF-8 before passing it to the application, and encodes all response data as UTF-8 before sending it back to the server. This is almost certainly what you should be doing in any new applications - UTF-8 is used by over half of all websites. If you need to handle different encodings, however, you can adjust the request object to handle things however you want. The encoding method will allow you to set any encoding supported by Encode, or undef to do no encoding at all. For instance:


1: 
2: 
3: 
4: 
5: 
6: 
7: 

 

sub index {
    my $self = shift;
    my ($r) = @_;
    $r->encoding('latin1');
    my $page = $r->param('page');
    # ...
}

 

This will set $page to the value of the page parameter, assuming that the request encoded the page parameter using the latin1 encoding.

The encoding value is also used to encode the response. By default, all responses will be encoded as UTF-8, but if you need to return something like a binary file, you can do this:


1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
10: 
11: 

 

sub index {
    my $self = shift;
    my ($r) = @_;
    # ...
    $r->encoding(undef);
    return [
        200,
        [ 'Content-Type' => 'application/pdf' ],
        [ $pdf_contents ],
    ];
}

 

This ensures that the binary data in the file will not be corrupted by trying to encode it as UTF-8 before returning it.

Routing details

You can also access the route description for the matched route via the $r->mapping method. This will return a hashref containing all of the path variables. In addition, this hashref may contain additional data, either added by the route builder or specified in the route description itself. For instance, the ControllerAction route builder adds keys for controller and action, and the HTTPMethod route builder adds a controller key.

You can specify additional elements to add to the mapping hashref in your route descriptions by specifying them in the hash along with your variable validations - values specified in this way are called defaults. For instance:


1: 
2: 
3: 
4: 
5: 
6: 
7: 

 

route '/news.xml' => 'feeds.news', (
    formatter => 'Data::Feed::RSS',
);

route '/news.atom' => 'feeds.news', (
    formatter => 'Data::Feed::Atom',
);

 

In this case, the mapping hashref will contain a key for formatter which contains the name of the formatter class to use. The news action can then use this value to determine how to format the response, rather than having to guess by inspecting the request path.

OX::Response

If you need to return more complicated responses (with headers, cookies, and things like that), you can use OX::Response (a subclass of Web::Response) to make this process easier. You can create an OX::Response object by calling the new_response method on the request object, and then setting the various values via methods on the response object. For instance:


1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
10: 

 

my $res = $r->new_response;
$res->status(200);
if ($is_internet_explorer) {
    $res->content_type('application/vnd.ms-excel');
}
else {
    $res->content_type('text/csv');
}
$res->content("foo,bar\nbaz,quux\n");
return $res;

 

new_response can also take key/value pairs to populate initial values for status, headers, content, etc, or it can also take a valid (possibly partial) PSGI response to set some initial values:


1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 

 

my $res = $r->new_response([200, ["X-My-App" => "MyApp"]]);
if ($is_internet_explorer) {
    $res->content_type('application/vnd.ms-excel');
}
else {
    $res->content_type('text/csv');
}
$res->content("foo,bar\nbaz,quux\n");
return $res;

 

See Web::Response for more details about the full functionality available.

Gravatar Image This article contributed by: Jesse Luehrs <jesse.luehrs@iinteractive.com>