Route Builders and Actions
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: | router as { |
/
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:
-
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(@_);
}
-
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 namedany
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 totext/html
.An OX::Response object
This will use the result of calling the
finalize
method. This will typically be generated by callingnew_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.