Dear reader
Would it make sense to define the routes as annotations directly at the route callables? I am wondering what you think are the pros and cons to do that.
Because today I started to develop such a feature. Currently I can annotate a class as a route group using @RouteGroup and a method of the class as a route using @Route. Note that closures are not supported. So for example
/**
* @RouteGroup("/user")
*/
class UserController
{
/**
* @Route("/{id}", name="userView")
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @param array $args
* @return ResponseInterface
*/
public function view(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
$response->getBody()->write('VIEW '.$args['id']);
return $response;
}
/**
* @Route(pattern="/add", methods={"POST"})
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @param array $args
* @return ResponseInterface
*/
public function add(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
$response->getBody()->write('Add User Called');
return $response;
}
/**
* @Route(pattern="/delete/{id}", methods={"delete"})
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @param array $args
*
* @return ResponseInterface
*/
public function delete(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
$response->getBody()->write('DELETE');
return $response;
}
}
So this class actually defines a route group with the pattern /user
containig three different routes.
It is even possible to define a route name as well as route middleware (and route group middleware as well), for example
/**
* @Route(
* "/",
* name="home",
* middleware={"App\TestRouteMiddleware"},
* )
*/
Again, closures as middleware are not supported.
The tool provides a composer binary that can be run in order to “compile” those annotations into a proper json-file. The tool has also a route loader that can be used to load this json-file and add the routes and route groups to the app, for example
$routeLoader = new RouteLoader($app);
$routeLoader->loadFromJson(__DIR__.'/../config/routes.json');
The tool can be configured with mappings of namespaces to route groups. So it is possible for example to define the namespace App\Controllers\Api
to be a route group with the pattern /api
and all annotated routes that are in classes that are in that namespace would be part of that route group.
It is also possible to define a parent to any route group. The parent has to be another route group, that is either a class annotated as route group or a namespace defined as route group.
So, thanks to the parent property of the @RouteGroup
annotation, the annotated routes in the following class would be part of the namespace route group App\Controllers\Api
that had been configured to have the pattern /api
.
/**
* @RouteGroup("/article", parent="App\Controllers\Api")
*
* @package App\Controllers
*/
class ArticleController
{
/**
* @Route("/read", name="readArticle")
*
* @param ServerRequestInterface $serverRequest
* @param ResponseInterface $response
* @param array $args
* @return ResponseInterface
*/
public function read(
ServerRequestInterface $serverRequest,
ResponseInterface $response,
array $args
): ResponseInterface {
$response->getBody()->write('Read Article');
return $response;
}
}
Hence the path for the route readArticle
would be /api/article/read
.
What are your thoughts about that?