PHPackages                             mrcl/slim-routes - 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. mrcl/slim-routes

ActiveLibrary[Framework](/categories/framework)

mrcl/slim-routes
================

Routing attributes for Slim Framework

0.0.1(4y ago)2681MITPHPPHP ^8.1CI failing

Since Dec 27Pushed 4y ago2 watchersCompare

[ Source](https://github.com/devmrcl/slim-routes)[ Packagist](https://packagist.org/packages/mrcl/slim-routes)[ RSS](/packages/mrcl-slim-routes/feed)WikiDiscussions main Synced today

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

SlimRoutes
==========

[](#slimroutes)

PHP8 attributes for easier and cleaner routing in [Slim](https://www.slimframework.com/).

Table of contents
=================

[](#table-of-contents)

- [Installation](#installation)
- [Usage](#usage)
    - [Attributes](#attributes)
    - [Configuration](#configuration)
- [Further Information](#further-information)
    - [Route patterns](#route-patterns)
    - [Middleware](#middleware)
    - [HTTP methods](#http-methods)
    - [Grouping routes](#grouping-routes)
    - [API versioning](#api-versioning)

Installation
============

[](#installation)

SlimRoutes requires &gt;= PHP 8.1

```
composer require mrcl/slim-routes

```

Usage
=====

[](#usage)

Attributes
----------

[](#attributes)

### Controller

[](#controller)

[`#[Controller]`](src/Attribute/Controller.php) marks a controller class as routable.

```
use Mrcl\SlimRoutes\Attribute\Controller;

#[Controller]
class UserController
{...}
```

#### Controller parameters

[](#controller-parameters)

ParameterDescriptionpatternPrefixes all routes' patternmiddlewareAdds middleware to all routesversionSpecify the basic API version(s) for all routes
Can get overriden by routegroupIdGroup all routes by specific group configuration
Can get overriden by route### Route

[](#route)

[`#[Route]`](src/Attribute/Route.php) maps a route to an action.
By default, it uses the `GET` method.

```
use Mrcl\SlimRoutes\Attribute\Route;

#[Route('users/{id}')]
class ViewUserAction
{
    public function __invoke
}

Routes:
-> GET /users/{id}
```

```
use Mrcl\SlimRoutes\Attribute\Controller;
use Mrcl\SlimRoutes\Attribute\Route;
use Mrcl\SlimRoutes\Routing\HttpMethod;

#[Controller('users')]
class UserController
{
    #[Route('{id}')]
    public function getUser

    #[Route(method: HttpMethod::POST)]
    public function addUser
}

Routes:
-> GET  /users/{id}
-> POST /users
```

#### Route parameters

[](#route-parameters)

ParameterDescriptionpatternRoute patternmethodHTTP method(s)middlewareRoute middlewareversionSpecify the route's API version(s)groupIdUse specific group configurationpriorityPrioritize routenameUnique route nameConfiguration
-------------

[](#configuration)

### Minimal configuration

[](#minimal-configuration)

For a minimal configuration you only need to pass an instance of the `Slim/App` (or any other class which implements `Slim\Interfaces\RouteCollectorInterface` or `Slim\Interfaces\RouteCollectorProxyInterface`) and directories where your action/controller classes are located.

```
use Mrcl\SlimRoutes\SlimRoutes;
use Slim\Factory\AppFactory;

$app = AppFactory::create();
$sr = new SlimRoutes(
    $app,
    __DIR__ . '/../src'
);
$sr->registerRoutes();
```

> Note: `#[Controller(version, groupId)]` and `#[Route(version. groupId, priority)]` do not work without configuration.

### Configuration options

[](#configuration-options)

#### Caching

[](#caching)

Recommended for production usage.

```
$sr->enableCache($cacheFile)
```

#### Additional directory

[](#additional-directory)

Add another directory to search for routable classes.

```
$sr->addDirectory($directory)
```

#### File name pattern

[](#file-name-pattern)

You can minimize the amount of scanned classes by setting a file name/extension pattern (regex).
Recommended if you have a lot of other classes in your folders and/or you do not use caching (e.g. in development).

```
$sr->setFileNamePattern($fileNamePattern, $fileExtensionPattern = 'php')
```

Example:
All wanted file names end with 'Controller' and file extensions are 'php' or 'PHP'

```
Regex: /^(.+Controller)\.(php|PHP)$/
setFileNamePattern('.+Controller', 'php|PHP')
```

Options for `*Action.php` and `*Controller.php` files are ready to use.

```
$sr->useActionFilePattern($fileExtensionPattern = 'php')
// OR
$sr->useControllerFilePattern($fileExtensionPattern = 'php')
```

#### Groups

[](#groups)

```
$sr->addGroup($groupConfiguration)
```

For more details, see [Advanced grouping with groups](#advanced-grouping-with-groups).

#### API version

[](#api-version)

```
$sr->addApiVersion($versionConfiguration)
```

For more details, see [API versioning](#api-versioning).

#### Route priority

[](#route-priority)

If you want to prioritize your routes, you need to enable it first. Predefined constants are available in [`RoutePriority`](src/Routing/RoutePriority.php).

```
$sr->enableRoutePrioritization($defaultPriority = RoutePriority::NORMAL)
```

If you plan to use your own range of priorities, you can pass a `defaultPriority`. Priorities are simple integers, the lower the number the higher the priority (better position in the route stack).

#### Change mapping of *ANY*

[](#change-mapping-of-any)

The special `HttpMethod::ANY` maps "any" HTTP method to your route.

By default, it maps to `GET`, `POST`, `PUT`, `PATCH`, `DELETE` and `OPTIONS` (like in Slim).

You can configure it to your own needs:

```
$sr->setAnyHttpMethods($methods, $override = true)
```

Further information
===================

[](#further-information)

Route patterns
--------------

[](#route-patterns)

### Leading slash

[](#leading-slash)

You may have noticed that all route patterns in this documentation do not use a leading `/`. They are automatically added on route generation.
If you prefer to use leading slashes, just use them.

### Pattern order

[](#pattern-order)

Depending on Slim configuration a base path or group can be the first pattern element.

`[/Slim][/ApiVersion][[/Parent...Group]/Group][/Controller]/Route`

Middleware
----------

[](#middleware)

Unlike in Slim added middleware runs in the order you set it.

```
#[Controller('users', [FirstMiddleware::class, SecondMiddleware::class])]
class UserController {
    #[Route(middleware: [ThirdMiddleware::class, FourthMiddleware::class])]
    public function getAllUsers
}
```

> Request &gt; FirstMiddleware &gt; SecondMiddleware &gt; ThirdMiddleware &gt; FourthMiddleware
> `UserController:getAllUsers`
> FourthMiddleware &gt; ThirdMiddleware &gt; SecondMiddleware &gt; FirstMiddleware &gt; Response`

### Middleware order

[](#middleware-order)

Added middleware on Slim level is always the first to be run.

`[SlimMiddleware][ApiVersionMiddleware][[ParentGroup...Middleware]GroupMiddleware][ControllerMiddleware][RouteMiddleware]`

HTTP methods
------------

[](#http-methods)

SlimRoutes comes with [predefined constants](src/Routing/HttpMethod.php) of the most used HTTP methods.
Also see, [Change mapping of ANY](#change-mapping-of-any).

Grouping routes
---------------

[](#grouping-routes)

### Controller pattern

[](#controller-pattern)

By using the `#[Controller]` attribute you have the option to pass a `pattern` which prefixes all routes within the class.

```
#[Controller('users')]
class UserController {
    #[Route]
    public function getAllUsers

    #[Route('{id}')]
    public function getUser
}

Routes:
-> GET /users
-> GET /users/{id}
```

### Advanced grouping with groups

[](#advanced-grouping-with-groups)

If you want to simply group action classes or have a more complex route setup and do not want to reassign patterns and middleware all the time, you can configure groups to use in your routes.

You can use an extra class for defining [`GroupConfiguration`](src/Routing/GroupConfiguration.php)s.

```
use Mrcl\SlimRoutes\Routing\GroupConfiguration;

class Group
{
    final public const ANIMALS   = 'animals';
    final public const CATS      = 'cats';
    final public const ELEPHANTS = 'elephants';

    private array $groups;

    public function __construct()
    {
        $this->groups = [
            self::ANIMALS => ($animals = new GroupConfiguration(id: self::ANIMALS, pattern: 'animals', middleware: AnimalsMiddleware::class)),
            self::ELEPHANTS => new GroupConfiguration(id: self::ELEPHANTS, pattern: 'elephants', middleware: ElephantsMiddleware::class, parent: $animals),
            self::CATS => new GroupConfiguration(id: self::CATS, pattern: 'cats', middleware: CatsMiddleware::class, parent: $animals)
        ];
    }

    public function get(string $id): GroupConfiguration
    {
        return $this->groups[$id];
    }
}
```

Add groups to SlimRoutes

```
$sr
  //->addGroup(Group->get(Group::ANIMALS)) you only need to add a group if you use it directly
  ->addGroup(Group->get(Group::CATS))
  ->addGroup(Group->get(Group::ELEPHANTS))
```

Pass the group's ID

```
#[Controller(groupId: Group::CATS)]
class CatsController {
    #[Route]
    public function getAllCats

    #[Route('{id}')]
    public function getCat
}

Routes:
-> GET /animals/cats      [AnimalsMiddleware, CatsMiddleware]
-> GET /animals/cats/{id} [AnimalsMiddleware, CatsMiddleware]
```

```
#[Route(method: HttpMethod::POST, groupId: Group::ELEPHANTS)]
class AddElephantAction
{
    public function __invoke
}

Routes:
-> POST /animals/elephants [AnimalsMiddleware, ElephantsMiddleware]
```

API versioning
--------------

[](#api-versioning)

For enabling API versioning to all of your routes, you have to configure an [`VersionConfiguration`](src/Routing/VersionConfiguration.php).

```
$sr->addApiVersion(new VersionConfiguration(version: 'v1', middleware: MyMiddleware::class))
```

### Multiple API versions

[](#multiple-api-versions)

Let's assume you have three API versions `v1`, `v2`, `v3`.

- v1 is only for some legacy routes, e.g. `/v1/updates`
- v3 is the latest and just went live, users are in the process of updating
- v2 is still used by the majority of users

A possible configuration could look like the following:

```
use Mrcl\SlimRoutes\Routing\VersionConfiguration;

$sr
  ->addApiVersion(new VersionConfiguration(version: 'v1', middleware: ApiV1Middleware::class, priority: RoutePriority::LOW, default: false))
  ->addApiVersion(new VersionConfiguration(version: 'v2', middleware: ApiV2Middleware::class))
  ->addApiVersion(new VersionConfiguration(version: 'v3', middleware: [ApiMiddleware::class, OtherApiMiddleware::class]))
  ->enableApiVersionPrioritization()
  ...
```

#### Route order

[](#route-order)

The route stack would contain routes in the following order

```
/v3/route1
/v2/route1
/v3/route2
/v2/route2
...
all v3 and v2 routes
...
/v1/...

```

You can still use the `priority` argument on routes to lower or heighten their position.

#### Versioning for specific routes

[](#versioning-for-specific-routes)

We have the following additional config

```
  ...
  ->addRouteGroup(new GroupConfiguration(id: 'cats-v1', pattern: 'cats'))
  ->addRouteGroup(new GroupConfiguration(id: 'cats', pattern: 'cats', middleware: CatsMiddleware::class))
  ->enableRoutePrioritization()
```

For a controller setup a possible config could be:

```
#[Controller(groupId: 'cats')]
class CatController {
    #[Route]
    public function getAllCats

    #[Route(
      pattern: 'all',
      groupId: 'cats-v1',
      version: 'v1'
    )]
    public function getAllCatsV1
}

Routes:
-> GET /v3/cats     [ApiMiddleware, OtherApiMiddleware, CatsMiddleware]
-> GET /v2/cats     [ApiV2Middleware, CatsMiddleware]
-> GET /v1/cats/all [ApiV1Middleware]
```

For action classes:

```
#[Route(groupId: 'cats')]
class ViewCatsAction {
    public function __invoke
}
```

```
#[Route(
  pattern: 'all',
  groupId: 'cats-v1',
  version: 'v1'
)]
class ViewCatsActionV1 {
    public function __invoke
}
```

### Unversioned routes

[](#unversioned-routes)

#### Exclude only some routes

[](#exclude-only-some-routes)

If you want to exclude some routes from versioning you can do so by pass `VersionConfiguration::NONE` to the `#[Route]`or `#[Controller]`attribute.

```
#[Route(
  pattern: 'my-action',
  version: VersionConfiguration::NONE
)]
class MyAction
{
    public function __invoke
}
```

Additionally, if **all of your unversioned** routes need some specific middleware you can add a `VersionConfiguration`.

```
$sr->addApiVersion(new VersionConfiguration(VersionConfiguration::NONE, SomeMiddleware::class, default: false))
```

#### Make all routes available without version

[](#make-all-routes-available-without-version)

If you have the special case that **all routes** (without specific version assignment) need also to be accessed without versioning you can do so

```
$sr->addApiVersion(new VersionConfiguration(VersionConfiguration::NONE))
```

### Versioned route names

[](#versioned-route-names)

When you add an API version and use route names, route names will be prefixed with the added version(s).

```
$sr
  ->addApiVersion(new VersionConfiguration('v1'))
  ->addApiVersion(new VersionConfiguration('v2'))
```

```
#[Route(name: 'my-action')]
class MyAction
{
    public function __invoke
}
```

Route names are `v1-my-action` and `v2-my-action`

###  Health Score

24

—

LowBetter than 32% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity48

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

1595d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2f0afa073ac38d579328cc4fab8b93f051ce5d3c88b55300b0359f5e31ea2830?d=identicon)[mrcl](/maintainers/mrcl)

---

Top Contributors

[![devmrcl](https://avatars.githubusercontent.com/u/72648622?v=4)](https://github.com/devmrcl "devmrcl (3 commits)")

---

Tags

slimroutingattributes

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/mrcl-slim-routes/health.svg)

```
[![Health](https://phpackages.com/badges/mrcl-slim-routes/health.svg)](https://phpackages.com/packages/mrcl-slim-routes)
```

###  Alternatives

[slim/twig-view

Slim Framework 4 view helper built on top of the Twig 3 templating component

3708.0M208](/packages/slim-twig-view)[mathmarques/smarty-view

Slim Framework 4 view helper built on top of the Smarty templating component

24134.7k1](/packages/mathmarques-smarty-view)[projek-xyz/slim-plates

Render your Slim 3 application views using Plates template engine.

2678.2k3](/packages/projek-xyz-slim-plates)[adbario/slim-secure-session-middleware

Secure session middleware for Slim 3 framework

2932.3k2](/packages/adbario-slim-secure-session-middleware)[bnf/slim3-psr15

PSR-15 middleware support for Slim Framework v3

10177.0k5](/packages/bnf-slim3-psr15)[martynbiz/slim3-controller

Provides controller functionality to Slim Framework v3. Also includes PHPUnit TestCase for testing controllers.

2814.4k1](/packages/martynbiz-slim3-controller)

PHPackages © 2026

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