Search by

icanboogie / bind-routing

olvlvl

Binds icanboogie/routing to ICanBoogie.

Package info

github.com/ICanBoogie/bind-routing

Homepage

pkg:composer/icanboogie/bind-routing

Statistics

Installs: 4 229

Dependents: 3

Suggesters: 0

Stars: 0

Open Issues: 0

6.0 2024-12-06 23:01 UTC

This package is auto-updated.

Last update: 2026-10-21 18:21:59 UTC


README

Release Code Coverage Downloads

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.

Tests Static Analysis Code Style

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.