Маршрутизация
Регистрация маршрутов, параметры, группы и маршрутизация через атрибуты.
Содержание
Ручная регистрация маршрутов
Используйте RouteRegistrar для регистрации маршрутов с помощью fluent API. Доступны сокращённые методы для основных HTTP-глаголов:
use AsceticSoft\Waypoint\RouteRegistrar;
$registrar = new RouteRegistrar();
// Полная форма
$registrar->addRoute('/users', [UserController::class, 'list'], methods: ['GET']);
// Сокращения
$registrar->get('/users', [UserController::class, 'list']);
$registrar->post('/users', [UserController::class, 'create']);
$registrar->put('/users/{id}', [UserController::class, 'update']);
$registrar->delete('/users/{id}', [UserController::class, 'destroy']);
// Любой другой HTTP-метод (PATCH, OPTIONS и т.д.)
$registrar->addRoute('/users/{id}', [UserController::class, 'patch'], methods: ['PATCH']);
После регистрации передайте коллекцию в Router:
$router = new Router($container, $registrar->getRouteCollection());
Параметры методов
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
$path |
string |
— | Шаблон маршрута (например, /users/{id}) |
$handler |
array\|Closure |
— | [Class::class, 'method'] или замыкание |
$middleware |
string[] |
[] |
Middleware для конкретного маршрута |
$name |
string |
'' |
Необязательное имя маршрута |
$priority |
int |
0 |
Приоритет сопоставления (чем выше, тем раньше) |
Параметры маршрутов
Параметры используют плейсхолдеры в стиле FastRoute:
// Базовый параметр — соответствует любому сегменту без слеша
$registrar->get('/users/{id}', [UserController::class, 'show']);
// Ограниченный параметр — только цифры
$registrar->get('/users/{id:\d+}', [UserController::class, 'show']);
// Несколько параметров
$registrar->get('/posts/{year:\d{4}}/{slug}', [PostController::class, 'show']);
Параметры автоматически внедряются в обработчик по имени с приведением типов:
$registrar->get('/users/{id:\d+}', function (int $id) {
// $id автоматически приведён к int
});
Используйте regex-ограничения вроде \d+ для ограничения формата параметров. Это предотвращает неоднозначные совпадения и улучшает производительность.
Маршрутизация через атрибуты
Объявляйте маршруты прямо на классах контроллеров с помощью атрибута #[Route]:
use AsceticSoft\Waypoint\Attribute\Route;
#[Route('/api/users', middleware: [AuthMiddleware::class])]
class UserController
{
#[Route('/', methods: ['GET'], name: 'users.list')]
public function list(): ResponseInterface { /* ... */ }
#[Route('/{id:\d+}', methods: ['GET'], name: 'users.show')]
public function show(int $id): ResponseInterface { /* ... */ }
#[Route('/', methods: ['POST'], name: 'users.create')]
public function create(ServerRequestInterface $request): ResponseInterface { /* ... */ }
#[Route('/{id:\d+}', methods: ['PUT'], name: 'users.update')]
public function update(int $id, ServerRequestInterface $request): ResponseInterface { /* ... */ }
#[Route('/{id:\d+}', methods: ['DELETE'], name: 'users.delete')]
public function delete(int $id): ResponseInterface { /* ... */ }
}
Атрибут #[Route] на уровне класса задаёт префикс пути и общие middleware. Атрибуты на методах определяют конкретные маршруты. Атрибут является повторяемым — один метод может обрабатывать несколько маршрутов.
Загрузка атрибутов
$registrar = new RouteRegistrar();
// Загрузить конкретные классы контроллеров
$registrar->loadAttributes(
UserController::class,
PostController::class,
);
// Или просканировать директорию
$registrar->scanDirectory(__DIR__ . '/Controllers', 'App\\Controllers');
// С фильтрацией по имени файла
$registrar->scanDirectory(__DIR__ . '/Controllers', 'App\\Controllers', '*Controller.php');
Параметры атрибута
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
$path |
string |
'' |
Шаблон пути (префикс на классе, маршрут на методе) |
$methods |
string[] |
['GET'] |
HTTP-методы (игнорируется на уровне класса) |
$name |
string |
'' |
Имя маршрута |
$middleware |
string[] |
[] |
Middleware (на уровне класса добавляются перед уровнем метода) |
$priority |
int |
0 |
Приоритет сопоставления (чем выше, тем раньше) |
Группы маршрутов
Объединяйте связанные маршруты под общим префиксом и middleware:
$registrar->group('/api', function (RouteRegistrar $registrar) {
$registrar->group('/v1', function (RouteRegistrar $registrar) {
$registrar->get('/users', [UserController::class, 'list']);
// Совпадение: /api/v1/users
});
$registrar->group('/v2', function (RouteRegistrar $registrar) {
$registrar->get('/users', [UserV2Controller::class, 'list']);
// Совпадение: /api/v2/users
});
}, middleware: [ApiAuthMiddleware::class]);
Группы могут быть вложенными. Префиксы и middleware накапливаются от внешних к внутренним группам.
Приоритетное сопоставление
Когда несколько маршрутов могут совпасть с одним URL, используйте параметр $priority для управления:
// Более высокий приоритет = проверяется первым
$registrar->get('/users/{action}', [UserController::class, 'action'], priority: 0);
$registrar->get('/users/settings', [UserController::class, 'settings'], priority: 10);
Маршруты с более высоким значением приоритета проверяются раньше. Маршруты с одинаковым приоритетом сопоставляются в порядке регистрации.