Keeper routes are accessible via global Spiral\Router\RouterInterface
. You can register them directly in the router
or via keeper bootloader and annotations. The last options allow you to isolate all routes in the given namespace.
GuardInterceptor is added to the KeeperCore by default, use @GuardNamespace
and @Guarded
to create a permission.
If @Guarded
annotation is missed, KeeperCore will protect a method using namespace.controller.method
permission
as a fallback.
New route should be declared after the parent::boot()
call. Controllers must be declared before the route declaration:
<?php
declare(strict_types=1);
use Spiral\Boot\BootloadManager;
use Spiral\Keeper\Bootloader;
use Spiral\Router\RouterInterface;
class AdminBootloader extends Bootloader\KeeperBootloader
{
protected const NAMESPACE = 'admin';
protected const PREFIX = '/admin';
public function boot(BootloadManager $bootloadManager, RouterInterface $appRouter): void
{
parent::boot($bootloadManager, $appRouter);
// Controllers are used via aliases
$this->addController('user', 'App\Admin\Controller\User');
$this->addRoute('/users/new', 'user', 'new', ['GET'], 'createUser');
}
}
The next routes will be created (see php app.php route:list
output):
+-------------------+--------+------------------+---------------------------------- +
| Name: | Verbs: | Pattern: | Target: |
+-------------------+--------+------------------+---------------------------------- +
| admin[createUser] | POST | /admin/users/new | App\Admin\Controller\User->create |
| admin[user.new] | GET | /admin/users/new | user->new |
+-------------------+--------+------------------+---------------------------------- +
Note
Routes will be duplicated by a generated name likecontroller.method
.
Attributes is a more convenient way because annotated routes allows you to use sitemaps - another powerful submodule for building menu navigation and breadcrumbs.
\Spiral\Keeper\Annotation\Action
and \Spiral\Keeper\Annotation\Controller
attributes are available. They should be
used together.
Controller
defines:
namespace
(optional, keeper
by default)name
/alias (required)prefix
(optional), used for all actions within the controllerdefaultAction
(optional)Action
works pretty much the same as a basic Route
annotation from the framework annotated routes. It defines:
route
pattern (required)name
(optional, controller.action
will be used as a fallback)methods
(optional)defaults
(optional)group
(not used for now)middleware
(optional)Example:
<?php
declare(strict_types=1);
use Spiral\Keeper\Annotation\Action;
use Spiral\Keeper\Annotation\Controller;
use Spiral\Views\ViewsInterface;
#[Controller(namespace: "admin", name: "user", prefix: "/users")]
class User
{
#[Action(route: "/create", name: "createUser", methods: "GET")]
public function create(ViewsInterface $views): string
{
return $views->render('admin:users/create');
}
}
The next routes will be created (see php app.php route:list
output):
+--------------------+--------+---------------------+--------------+
| Name: | Verbs: | Pattern: | Target: |
+--------------------+--------+---------------------+--------------+
| admin[createUser] | GET | /admin/users/create | user->create |
| admin[user.create] | GET | /admin/users/create | user->create |
+--------------------+--------+---------------------+--------------+
Note
Routes will be duplicated by a generated name likecontroller.method
.
You can either call a route by its name directly or using a RouteBuilder
/**
* @var \Spiral\Router\RouterInterface $router
* @var \Spiral\Keeper\Helper\RouteBuilder $routeBuilder
*/
$router->uri('admin[user.create]');
$routeBuilder->uri('admin', 'user.create');
The output will be the same: /admin/users/new
Note
RouteBuilder
takes care about namespace isolation pattern.
To enable default controller routing it should be added explicitly to the config.
Either via KeeperBootloader::DEFAULT_CONTROLLER
value or via config file:
return [
'routeDefaults' => ['controller' => 'App\Admin\Controller'],
];
Default controller action can be also defined either in the config:
return [
'routeDefaults' => ['controller' => 'App\Admin\Controller', 'action' => 'list'],
];
or via defaultAction
property in @Controller
annotation.
Note
For default controllerindex
method will be used as a fallback if nodefaultAction
provided in the default controller annotation.