Skip to content

Routing

Routing in NaN is handled by the NaN\App\Middleware\Router namespace. All routers are PSR-15-compatible middleware. The default way to register routes in NaN is with the RoutesCollection router and Route classes. The Route class is also a PSR-15-compatible middleware.

Comes packaged with the application component.

use NaN\App\Middleware\{
MiddlewareCollection,
Router\Route,
Router\RoutesCollection,
};
use Psr\Http\Message\ResponseInterface;
$router = new RoutesCollection(
new Route(
'/posts', // static path
function (): ResponseInterface {}, // handler
'posts', // name
new MiddlewareCollection(), // middleware
),
new Route(
'/posts/{id}', // parameterized path
function (int $id): ResponseInterface {}, // handler
'post', // name
),
);

Internally, RoutesCollection uses a radix trie. Performance-wise, there shouldn’t be any concerns. Benchmark results measure registering 1000 routes occurring in about 1 millisecond, and looking up a single route occurs within microseconds, whether static or parameterized.

When using parameterized routes, the part within the curly brackets is the parameter’s name. The parameter name must obey PHP variable naming rules, since they will be autowired into their handlers. Since parameters are designed to be simple, they will match anything wherever used. Nevertheless, static routes will take precedence over parameterized routes.

Using closures for route handlers will match against every HTTP method. To have routes match only against certain HTTP methods you can use request validators provided by the NaN\Http namespace as route middleware.

use NaN\Http\Request\Validators\GetRequestValidator;
$route = new Route(
'/',
function () {},
middleware: new GetRequestValidator(),
);

For more information on request validators, see the http component.

To have fine-tuned control over multiple HTTP methods, you’ll need to make use of controllers. NaN provides several interfaces and traits that you should be aware of.

Currently, to create a controller you’ll need to implement the ControllerInterface interface. To simplify development, we provide a matching ControllerTrait trait.

use NaN\App\Controller\Interfaces\ControllerInterface;
use NaN\App\Controller\Traits\ControllerTrait;
class HomeController implements ControllerInterface {
use ControllerTrait;
}
$route = new Route('/', HomeController::class);

The ControllerTrait trait judges your controllers by the controller interfaces they implement. It also provides placeholder methods for GET and HEAD.

The following interfaces, along with their matching traits, are available.

use NaN\App\Controller\Interfaces\{
ControllerInterface,
ConnectControllerInterface,
DeleteControllerInterface,
OptionsControllerInterface,
PatchControllerInterface,
PostControllerInterface,
PutControllerInterface,
TraceControllerInterface,
};
use NaN\App\Controller\Traits\{
ControllerTrait,
ConnectControllerTrait,
DeleteControllerTrait,
OptionsControllerTrait,
PatchControllerTrait,
PostControllerTrait,
PutControllerTrait,
TraceControllerTrait,
};

The application component autowires dependencies into routes. Unlike controllers, closures do not need to set their parameters as optional.

$route = new Route(
'/users/{id}',
function (
int $id,
SomeInterface $something,
): ResponseInterface {
},
'user',
);