icanboogie / bind-routing
Binds icanboogie/routing to ICanBoogie.
Requires
- php: >=8.2
- icanboogie/icanboogie: ^6.0
- icanboogie/inflector: ^3.0
- icanboogie/routing: ^6.0
Requires (Dev)
- icanboogie/console: ^6.0
- olvlvl/composer-attribute-collector: ^2.1
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.4
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
The icanboogie/bind-routing package binds ICanBoogie/Routing to ICanBoogie. It provides infrastructure to configure routes and responders, a trait to get URLs from objects, and commands to list routes and actions.
Installation
composer require icanboogie/bind-routing
Defining routes using attributes
Routes are defined by controllers, with the attributes of icanboogie/routing such as Get or Post. The class
attribute Prefix defines the prefixes shared by the methods. If left undefined, the action is inferred from the
controller class and the method name (SkillController::show is skills:show).
<?php namespace App\Presentation\HTTP; use ICanBoogie\HTTP\Response; use ICanBoogie\Routing\Attribute\Get; use ICanBoogie\Routing\Attribute\Post; use ICanBoogie\Routing\Attribute\Prefix; #[Prefix(route: '/skills')] final class SkillController { // This will create a 'GET /skills' route with 'skills:list' action #[Get] public function list(): Response { // … } // This will create a 'GET /skills/:slug' route with 'skills:show' action #[Get('/:slug')] public function show(string $slug): Response { // … } // This will create a 'POST /skills' route with 'skills:create' action #[Post] public function create(): Response { // … } }
Controllers are discovered with olvlvl/composer-attribute-collector, and registered as shared services:
<?php // app/all/config/routes.php namespace App; use ICanBoogie\Routing\ConfigBuilder; use ICanBoogie\Routing\CacheStrategy; return fn(ConfigBuilder $config) => $config ->enable_discovery() // Meant for production, use CacheStrategy::MEMOIZE in development. ->cache_strategy(CacheStrategy::COMPILE);
Use add_controller() to add a controller by hand, with an optional route builder instead of attributes. Such a
controller must be tagged with routing.controller, so it can be obtained from the container:
<?php use ICanBoogie\Routing\ConfigBuilder; use ICanBoogie\Routing\RouteBuilder; return fn(ConfigBuilder $config) => $config ->add_controller(ContactController::class, fn(RouteBuilder $r) => $r ->get('/contact.html', 'new') ->post('/contact.html', 'create'));
services: App\Presentation\HTTP\ContactController: tags: [ routing.controller ]
In development, use CacheStrategy::MEMOIZE.
Middleware
Middleware, see icanboogie/routing, wraps the responders, e.g. to require authentication. A
service implementing ICanBoogie\Routing\Middleware is tagged with routing.middleware when it is
registered with autoconfigure: true, and collected by the
ICanBoogie\Routing\MiddlewareCollection service, which wraps the responders provided by the
ActionResponderProvider service. There is nothing else to configure:
<?php namespace App\Presentation\HTTP; use ICanBoogie\HTTP\Responder; use ICanBoogie\Routing\Middleware; final class RequireAuthentication implements Middleware { public function responder(Responder $next): Responder { // … } }
services: _defaults: autowire: true autoconfigure: true App\Presentation\HTTP\RequireAuthentication: ~
Without autoconfigure, tag the service with routing.middleware yourself. The first middleware is the closest to the
endpoint, each following one wraps the previous. Order them with the priority of the tag, the highest first:
services: App\Presentation\HTTP\RequireAuthentication: tags: [ { name: routing.middleware, priority: 10 } ]
Legacy controllers
Controllers extending ControllerAbstract still work, but they have to be registered and tagged with
action_responder and action_alias, their routes have to be provided separately:
services: _defaults: autowire: true App\Presentation\HTTP\Controller\ArticleController: shared: false tags: - { name: action_responder } - { name: action_alias, action: 'articles:list' } - { name: action_alias, action: 'articles:show' }
Getting route configuration
The following code demonstrates how to obtain a route provider from the routes configuration:
<?php namespace ICanBoogie; /** @var Application $app */ $config = $app->config_for_class(Routing\Config::class); $routes = $config->routes;
Continuous Integration
The project is continuously tested by GitHub actions.
Code of Conduct
This project adheres to a Contributor Code of Conduct. By participating in this project and its community, you're expected to uphold this code.
Contributing
See CONTRIBUTING for details.