Define Route Requirements with Backed Enum in Symfony 7

Define Route Requirements with Backed Enum in Symfony 7

Route requirements help ensure that a particular route only match under specific conditions. Backed enums, available since PHP 8.1, enable you to create enumerations with explicitly defined values. Combining Symfony's routing with backed enums can enhance the codebase by ensuring that route requirements adhere to a predefined set of valid values. This tutorial shows how to define route requirements with backed enum in Symfony 7.

Let's say we have the following backed enum:

src/Enum/UserStatus.php

<?php

namespace App\Enum;

enum UserStatus: string
{
    case ACTIVE = 'A';
    case NOT_ACTIVE = 'N';
    case PENDING = 'P';
    case DELETED = 'D';
}

Using enum we can restrict the possible values of some routing parameter. Consider the following example:

src/Controller/TestController.php

<?php

namespace App\Controller;

use App\Enum\UserStatus;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Requirement\EnumRequirement;

class TestController
{
    #[Route('/{status}', requirements: [
        'status' => new EnumRequirement(UserStatus::class)],
    )]
    public function index(Request $request): Response
    {
        return new Response($request->attributes->get('status')); // A, N, P, or D
    }
}

The requirement is specified using the EnumRequirement class, which takes the UserStatus::class as an argument. This suggests that the status parameter must be a valid value from the UserStatus enum. Results in a 404 Not Found response when the provided value is not a valid value for the enum type.

It is also possible to only allow specific values of those defined in the enum.

src/Controller/TestController.php

<?php

namespace App\Controller;

use App\Enum\UserStatus;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Requirement\EnumRequirement;

class TestController
{
    #[Route('/{status}', requirements: [
        'status' => new EnumRequirement([UserStatus::ACTIVE, UserStatus::PENDING])],
    )]
    public function index(Request $request): Response
    {
        return new Response($request->attributes->get('status')); // A or P
    }
}

The code ensures that the status parameter must be either A or P, restricting the allowed values to a specific subset defined in the UserStatus enum. If a different value is provided, it would result in a 404 Not Found response.

Leave a Comment

Cancel reply

Your email address will not be published.