Default Route
Introduction
DefaultRoute class is good for all size projects, from small to large projects, from public pages, administration interfaces to API backends.
It supports:
- Modules and controllers and actions in each module
- Application (root) controllers and actions
- Two modes: Ajax/Action and RESTful mode on all controllers and actions
- Exception handling
There is no configuration file where you need to map route with the class and action. Instead, DefaultRoute will look for controller and action based on REQUEST_URI and configuration.
Configuration
As already mentioned in mandatory config, DefaultRoute accepts one parameter from routing_options:
always_restful
-true
orfalse
, if not present, default isfalse
If you want RESTful ability per controller and not on all routes, then keep always_restful
on false
,
and define static $resftul
to true
in controller itself, like this:
class ApiController
{
public static $restful = true;
}
RESTful Mode Always ON
If always_restful
is set to true
, then class will differently construct action (methods) names in
controller depending on request method. Supported HTTP methods are GET
, POST
, PUT
and DELETE
, so you're
able to map the same REQUEST_URI in four different ways, depending on the HTTP method.
For example, if you make POST=/users/list
, DefaultRoute will
- First look up for
users
module.
If users
module exists, it'll then look up the following controllers
and methods in users
module in exactly this order:
ListContoller->postIndex()
ListController->__call()
IndexController->postList()
IndexController->__call()
Other case:
users
module doesn't exist.
DefaultRoute will then inspect root controllers (in [applicationPath]/controllers
):
UsersContoller->postList()
UsersController->__call()
IndexController->postUsers()
IndexController->__call()
In both cases, if none of the controllers nor methods are found, DefaultRoute will throw \Koldy\Response\Exception\NotFoundException
.
RESTful Mode Always OFF
In this mode, you're able to map the same REQUEST_URI in only two different ways called Action
and Ajax
.
Ajax
requests are all methods which have the following conditions met:
- HTTP method must be
POST
- Header
X-Requested-With
must be present and have thexmlhttprequest
value
Most of the client side Javascript frameworks and libraries (such as jQuery) automatically adds that header, but in case you're using ajax library that doesn't do that automatically, you'll need to set it yourself.
If request is not Ajax request, then it's Action
.
For example, if you make GET=/users/list
, DefaultRoute will
- First look up for
users
module.
If users
module exists, it'll then look up the following controllers
and methods in users
module in exactly this order:
ListContoller->indexAction()
ListController->__call()
IndexController->listAction()
IndexController->__call()
Other case:
users
module doesn't exist.
DefaultRoute will then inspect the same controllers, but within the application root controllers (in [applicationPath]/controllers
):
UsersContoller->listAction()
UsersController->__call()
IndexController->usersAction()
IndexController->__call()
If this was Ajax
request, then all method names would have the Action
suffix instead of Ajax
.
As mentioned in configuration above, if you put public static $restful = true;
in your controller, then
naming of the methods within that class will be the same as if always_restful
was set to true
.
Before And After methods
DefaultRoute class respects before()
and after()
methods in controller classes. If you define before()
method in controller
and before()
method doesn't return anything or returns NULL
, DefaultRoute will continue with the execution of targeted method,
meaning you're able to override response before executing method. This is useful if you want to check the user session and if session
doesn't exists or has expired, you can return Redirect response from before()
method.
The after()
method does the same, except it's executed after response from targeted method is dumped to output buffer, meaning
that return value from after()
method is ignored.
Error Handling
If DefaultRoute fails to execute your method, it'll throw \Koldy\Response\Exception\ServerException
. If
controller or action (method) is not found after all attempts, DefaultClass will throw \Koldy\Response\Exception\NotFoundException
.
To catch these exceptions, you can define class ExceptionHandler
that extends \Koldy\Response\ResponseExceptionHandler
in
[applicationPath]/ExceptionHandler.php
and then override any or all methods from the extended class.
If you want to have exception handler per module, then do the same, just put ExceptionHandler
class within the controllers in the
module where you want to achieve overriding.
Using Default Route
Although there's \Koldy\Route
class which is helper for routes, it might behave differently depending on which routing
class you're using. The following examples will work for DefaultRoute.
To get the routing class instance, use:
use Koldy\Route;
use Koldy\Route\DefaultRoute;
$route = Route::getRoute();
echo Route instanceof DefaultRoute ? 'YES' : 'NO'; // will print YES
\Koldy\Route
class has some useful helpers. Imaging you're calling these methods under REQUEST_URI
/users/list/page/2?print=no
with no users
module:
Route::controller(); // returns 'users'
Route::isController('users'); // returns true
Route::action(); // returns 'list'
Route::isAction('list'); // returns true
Route::is('users', 'list'); // returns true
Route::isModule('users'); // return false
Route::getVar(2); // returns 'page' because it's 3rd "variable" in (users, list, page, 2)
Route::getVar('print'); // returns 'no'
Route::href('users', 'list', ['page', '2', 'print' => 'no']); // returns "/users/list/page/2?print=no"
Routes To Other Sites
If you're having multi-site configuration, then you'll need another configuration file configs/sites.php
which is
array of other sites where key is the name of the site you'll be using and value is domain with schema to other site.
Let's say you have this sites in configs/sites.php
:
return [
'web' => 'https://my.site.com',
'api' => 'https://api.site.com'
];
You can then use:
Route::siteHref('api', 'users', 'list', ['page', '2']); // returns "https://api.site.com/users/list/page/2"
Route::site('api', '/users/page/2'); // returns "https://api.site.com/users/page/2"
Routes To Assets
To have the proper routes to assets, first properly configure mandatory configuration. Then, when you know the keys from that config, you can simply use:
echo Route::asset('images/logo.png', 'dev'); // returns "http://localhost:3000/static/images/logo.png"