I guess the path configuration in the routes.php is faulty. Try this:
$app->get('/api/pages/{id:\d+}/users/{userId:\d+}', App\Page\PageHandler::class, 'api.pages');
In the handle function you can easily access userId
and id
via getAttributes function of the $request
object:
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$userId = (int)$request->getAttribute('userId');
$id = (int)$request->getAttribute('id');
}
The configuration in the ConfigProvider is not necessary for this.
If you want that getAttribute returns directly the corresponding entity objects and not the IDs, I would recommend you to use a middleware for it, which uses userId
and id
in order to loads the desired objects from the database or any other data source.
The following example uses Doctrine:
<?php
namespace App\Middleware;
class GetEntitiesFromQueryParamsMiddleware implements MiddlewareInterface
{
private $entityManager;
public function __construct(EntityManagerInterface $entityManager
{
$this->entityManager = $entityManager;
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$pageId = (int)$request->getAttribute('id');
$page = $this->entityManager
->getRepository(PageEntity::class)
->find($pageId);
$userId = (int)$request->getAttribute('userId');
$user = $this->entityManager
->getRepository(User::class)
->find($id);
return $handler->handle($request
->withAttribute(PageEntity::class, $page)
->withAttribute(User::class, $user));
}
}
Create a Factory for the middleware and register it in the ConfigProvider.
Also register this middleware in pipeline.php
after RouteMiddleware
:
...
$app->pipe(RouteMiddleware::class);
$app->pipe('/api/pages', GetEntitiesFromQueryParamsMiddleware::class);
...
Now you can access the objects in the handler method:
class PageHandler
{
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$page = $request->getAttribute(PageEntity::class);
$user = $request->getAttribute(User::class);
}
}