PHPackages                             componenta/router - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. componenta/router

ActiveLibrary[Framework](/categories/framework)

componenta/router
=================

HTTP route registration, matching, generation, and compiled route cache for Componenta applications

v1.0.0(1mo ago)083MITPHPPHP ^8.4

Since Jun 17Pushed 1mo agoCompare

[ Source](https://github.com/componenta/router)[ Packagist](https://packagist.org/packages/componenta/router)[ RSS](/packages/componenta-router/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (10)Versions (2)Used By (3)

Componenta Router
=================

[](#componenta-router)

Runtime HTTP router for Componenta applications. The package provides immutable route records, fluent route building, route groups, route collections, path pattern compilation, optimized compiled routes, URL generation, PSR-15 route matching and dispatch middleware, handler resolution, and router exception handlers.

Attribute discovery, production route-cache generation, and HTTP-interceptor route handler resolution live in `componenta/router-app`.

Installation
------------

[](#installation)

```
composer require componenta/router
```

Package Boundaries
------------------

[](#package-boundaries)

`componenta/router` owns runtime routing behavior. It can work with explicitly registered routes and does not require class scanning.

Related Packages
----------------

[](#related-packages)

PackageWhy it matters here`componenta/http-responder`Provides HTTP response helpers; router only selects handlers and does not format controller output.`componenta/middleware-factory`Turns strings, classes, groups, and middleware instances into `MiddlewareInterface`.`componenta/di`Creates route handlers and middleware from the container when needed.`componenta/router-app`Discovers `#[Route]` attributes, builds route cache files, and provides application HTTP-interceptor route handler resolution.Use `componenta/router` for:

- route records and route collections;
- route matching and URL generation;
- grouped routes and middleware groups;
- PSR-15 matching/dispatch middleware;
- compiled route collections loaded from cache;
- route exception handling.

Use `componenta/router-app` for:

- discovering `#[Route]` attributes;
- generating route cache files;
- integrating route compilation with the application cache pipeline;
- resolving route handlers through HTTP interceptors.

Route Records
-------------

[](#route-records)

`RouteRecord` is an immutable route definition.

```
use Componenta\Http\Router\RouteRecord;

$route = RouteRecord::get(
    name: 'posts.show',
    path: '/posts/{id}',
    handler: ShowPostController::class,
    middlewares: ['auth'],
    tokens: ['id' => '[0-9a-f-]{36}'],
);
```

Public fields:

FieldTypeMeaning`name``string`Unique route name used for matching result and URL generation.`path``string`Normalized route path.`handler``RouteHandler`Handler definition wrapped as route middleware.`methods``list`Uppercase HTTP methods.`middlewares``?MiddlewareGroup`Route-level middleware group.`tokens``array`Regex constraints for path parameters.`defaults``array`Scalar defaults for optional parameters.`group``?string`Group name to apply through `Routes`.Static constructors exist for `get`, `post`, `put`, `patch`, `delete`, `head`, `options`, and `any`.

`RouteRecord` validates early:

- method list must not be empty;
- every method must be a non-empty string;
- token patterns must be valid regular expressions;
- default values must be scalar or null.

Fluent Builder
--------------

[](#fluent-builder)

`RouteBuilder` is useful when a route is assembled conditionally.

```
use Componenta\Http\Router\RouteBuilder;

$route = RouteBuilder::get('posts.show', '/posts/[id]')
    ->handler(ShowPostController::class)
    ->token('id', '[0-9a-f-]{36}')
    ->default('preview', false)
    ->group('public')
    ->build();
```

`build()` throws `LogicException` when no handler was set.

Path Syntax
-----------

[](#path-syntax)

The default compiler uses `CompositeSyntax`, so several parameter syntaxes are accepted:

SyntaxMeaning`/posts/{id}`Required parameter.`/posts/[id]`Required parameter.`/posts/:id`Required parameter in colon syntax.`/posts/[?page]`Optional parameter.`/posts/[id:\d+]`Inline regex constraint.`/posts/[?page:\d+=1]`Optional parameter with regex and default.Explicit `tokens` override inline tokens. Explicit `defaults` override inline defaults.

Groups
------

[](#groups)

`RouteGroup` applies name prefix, path prefix, middleware, tokens, and defaults to child routes.

```
$routes = new Routes();

$api = $routes->group('api', '/api', middleware: ['api']);
$admin = $api->group('admin', '/admin', middleware: ['auth', 'admin']);

$admin->get('dashboard', '/dashboard', AdminDashboardController::class);
```

The route above is registered as:

- name: `api.admin.dashboard`
- path: `/api/admin/dashboard`
- middleware: `api`, `auth`, `admin`
- group: `api.admin`

Nested groups are registered in the parent collection, so later routes can reference the full group name explicitly.

Route Collection
----------------

[](#route-collection)

`Routes` implements:

- `RouteCollectorInterface`
- `MatcherInterface`
- `GeneratorInterface`
- `Countable`
- `IteratorAggregate`

```
$routes = new Routes();
$routes->addRoute(RouteRecord::get('home', '/', HomeController::class));

$match = $routes->match($routes, '/', 'GET');
$url = $routes->generate($routes, 'home');
```

`Routes` compiles static and dynamic lookup tables lazily after registration. Static routes use hash lookup. Dynamic routes use compiled regex patterns.

Router Facade
-------------

[](#router-facade)

`Router` combines a route collector, matcher, and generator.

```
$router = Router::fromDnf($routes);

$match = $router->match('/posts/42', 'GET');
$url = $router->generate('posts.show', ['id' => 42]);
```

`match()` throws:

- `RouteNotFoundException` when no route matches URI and method;
- `MethodNotAllowedException` when the URI matches but the method is not allowed.

`generate()` throws:

- `RouteNotRegisteredException` when the route name is missing;
- `InvalidArgumentException` when required parameters are missing or invalid.

Match Result
------------

[](#match-result)

`MatchResult` contains data needed for dispatch:

FieldType`name``string``handler``RouteHandler``middlewares``?MiddlewareGroup``parameters``array``route``RouteRecord` lazy propertyMatched parameters are cast from numeric strings to integers or floats when possible.

PSR-15 Middleware
-----------------

[](#psr-15-middleware)

`MatchRouteMiddleware` matches the incoming request and stores the result in request attributes:

- `MatchRouteMiddleware::ATTRIBUTE_MATCH_RESULT`
- every matched route parameter under its parameter name

`DispatchRouteMiddleware` reads the match result and resolves route middleware through `MiddlewareFactory`.

 ```
flowchart LR
    A["ServerRequestInterface"] --> B["MatchRouteMiddleware"]
    B --> C["request attributes"]
    C --> D["DispatchRouteMiddleware"]
    D --> E["route middleware group"]
    E --> F["route handler"]
```

      Loading `DispatchRouteMiddleware` resolves route middleware on every request. `MemoizedDispatchRouteMiddleware` keeps the same dispatch flow, but caches the resolved PSR-15 middleware object by route name.

The memoized variant does not cache `ServerRequestInterface`, route parameters, the terminal handler, or route handler results. Disable it when middleware definitions are intentionally request-dependent or container resolution is intentionally transient.

Router Exception Handlers
-------------------------

[](#router-exception-handlers)

HandlerBehavior`ThrowingRouterExceptionHandler`Re-throws router exceptions for a global error handler.`RouterExceptionHandler`Returns 404 or 405 PSR-7 responses.`JsonRouterExceptionHandler`Returns JSON 404/405 responses and `Allow` for 405.`CallableRouterExceptionHandler`Delegates handling to a closure.Compiled Routes
---------------

[](#compiled-routes)

`CompiledRoutes` is the optimized production collection loaded from a generated cache file.

```
$routes = CompiledRoutes::fromCache($cacheFile);
$router = Router::fromDnf($routes);
```

Performance model:

- static routes use O(1) hash lookup;
- dynamic routes can use one regex per HTTP method;
- large dynamic sets can be split into chunks;
- prefix index reduces the number of chunks checked;
- route handlers and middleware groups are initialized lazily.

The cache file is generated by `RouteCacheGenerator`, usually through `componenta/router-app`.

Attribute Route Metadata
------------------------

[](#attribute-route-metadata)

`#[Route]` is the runtime metadata class consumed by application discovery.

```
use Componenta\Http\Router\Attribute\Route;

#[Route('posts.show', '/posts/[id:\d+]', 'GET', middlewares: ['web'])]
final readonly class ShowPostController
{
    public function __invoke(int $id): ResponseInterface
    {
        // ...
    }
}
```

Constructor:

```
public function __construct(
    string $name,
    string $path,
    array|string $methods = ['GET'],
    array|string $middlewares = [],
    array $tokens = [],
    array $defaults = [],
    ?string $group = null,
    int $priority = 0,
)
```

`methods` accepts a string (`'GET'`), a `|`-separated string (`'GET|POST'`), or an array (`['GET', 'POST']`). `priority` is used by `componenta/router-app`: when multiple attribute routes can match the same URI, the route with the higher `priority` is added first.

The base router package does not scan this attribute. Discovery belongs to `componenta/router-app`.

Configuration
-------------

[](#configuration)

`ConfigProvider` registers:

- `RouteLocatorInterface`
- `Router`
- `MatchRouteMiddleware`
- `DispatchRouteMiddleware`
- `RouteHandlerResolver`
- `Compiler`
- `ThrowingRouterExceptionHandler`
- aliases for `CompilerInterface`, `RouterExceptionHandlerInterface`, `MatcherInterface`, and `GeneratorInterface`

Config keys:

KeyMeaning`ConfigKey::ROUTES_FILE`Path to route definition file.`ConfigKey::ROUTES_CACHE_FILE`Optional explicit route cache file path.`ConfigKey::CACHE_RESOLVED_ROUTE_MIDDLEWARE`Allows the factory to return `MemoizedDispatchRouteMiddleware` instead of plain `DispatchRouteMiddleware` when `COMPILED_PIPELINE` is also enabled.`ConfigKey::COMPILED_PIPELINE`Enables compiled router fast paths and allows memoized dispatch.Failure Model
-------------

[](#failure-model)

ExceptionWhen`RouteAlreadyExistsException`Duplicate route name registration.`RouteNotRegisteredException`URL generation references unknown route name.`RouteNotFoundException`URI/method cannot be matched.`MethodNotAllowedException`URI matches a route, but method is not allowed.`GroupNotFoundException`Requested group is absent.

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance91

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

43d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/20490712?v=4)[Andrey Shelamkoff](/maintainers/Shelamkoff)[@Shelamkoff](https://github.com/Shelamkoff)

---

Top Contributors

[![Shelamkoff](https://avatars.githubusercontent.com/u/20490712?v=4)](https://github.com/Shelamkoff "Shelamkoff (1 commits)")

### Embed Badge

![Health badge](/badges/componenta-router/health.svg)

```
[![Health](https://phpackages.com/badges/componenta-router/health.svg)](https://phpackages.com/packages/componenta-router)
```

###  Alternatives

[symfony/symfony

The Symfony PHP framework

31.4k87.2M2.2k](/packages/symfony-symfony)[cakephp/cakephp

The CakePHP framework

8.8k19.5M1.8k](/packages/cakephp-cakephp)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k17](/packages/tempest-framework)[spiral/framework

Spiral, High-Performance PHP/Go Framework

2.1k2.2M69](/packages/spiral-framework)[typo3/cms-core

TYPO3 CMS Core

3713.2M5.2k](/packages/typo3-cms-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
