2012 Feed

Route Builders and Actions

OX - 2012-12-02

The route keyword

The route keyword maps a path to an action spec. A path is a pattern that resembles a URI path, which OX attempts to match against the incoming request URI. An action spec can take many forms, but it essentially describes what code will run when the corresponding path is matched. The path syntax and features will be described tomorrow, but today's article is about how the action spec is interpreted.

Route builders

Route builders are the part of OX which takes an action spec and determines which code to run when its associated path is matched. For instance, in this router:


1: 
2: 
3: 
4: 

 

router as {
    route '/' => sub { "Hello world!" };
    route '/posts/:id' => 'posts.view';
};

 

/ uses a route builder which just calls the given coderef directly, while /posts/24 uses a route builder which generates a coderef to call the view method on the posts controller.

There are three default route builders for OX applications:

  • OX::RouteBuilder::Code


    1: 
     

    route '/' => sub { "Hello world!" };
     

    This route builder will be used whenever the action spec is a coderef. It is the most basic route builder - it just allows you to specify a coderef to call when the route is chosen.

  • OX::RouteBuilder::ControllerAction


    1: 
     

    route '/' => 'root.index';
     

    The ControllerAction route builder will be used if the action spec consists of two words (\w+) separated by a period. Those two words will be used to look up a controller to use and a method to call on that controller. The controller is looked up by name among the attributes on the OX application (really services, but we will discuss that when we explain Bread::Board).

    The code which is run for the above example is roughly equivalent to:


    1: 
    2: 
    3: 
    4: 

     

    sub {
        my $controller = $self->root;
        return $controller->index(@_);
    }

     
  • OX::RouteBuilder::HTTPMethod


    1: 
     

    route '/' => 'root';
     

    The HTTPMethod route builder will be used if the action spec consists of a single word (\w+). This word will be used to look up a controller as in the ControllerAction route builder, but the method to call will be the lowercase version of the HTTP method used (get, post, etc). If no appropriate method is found in the class, it will attempt to call the method named any instead. If that is also not found, the request will return a 405 error.

    The code which is run for the above example is roughly equivalent to:


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

     

    sub {
        my ($r) = @_;
        my $controller = $self->root;
        my $method = lc($r->method);
        $method = 'any' if !$controller->can($method);
        return [405, [], ["error"]] if !$controller->can($method);
        return $controller->$method(@_);
    }

     

You can also define your own route builders, but doing so will be covered in another article.

Actions

Once OX determines which code to run to fulfill the request, it will call that code. The code that is called will receive an OX::Request object as its first argument (other than the invocant, if called as a method), which can be used to access all of the request information. The action code should return the response to use, which can be any of:

  • Any valid PSGI response

    This will be used as-is.

  • A string

    This will result in a response with a 200 response code and Content-Type set to text/html.

  • An OX::Response object

    This will use the result of calling the finalize method. This will typically be generated by calling new_response on the request object that you receive.

All requests will be decoded and all responses will be encoded as UTF-8 automatically, so your application can deal entirely with Unicode strings. This behavior can be changed if necessary, but we will discuss that in a future post.

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