The main way to handle requests in symfony are
controllers . With the ability to describe routing directly in controllers (annotations), life has become even better. But the use of annotations when inheriting controllers causes problems - for each child controller it is necessary to re-register the routing. But in crud-applications, a typical situation is when there is a basic controller and many children, which inherit the logic of the basic controller, and routes for which could be generated automatically.
An attempt to improve the standard Symfony controllers was the
DunglasActionBundle . This bundle assumes that the controller has only one method __invoke (), which allows you to use the class name as the name of the route, which is very convenient. For example, you can generate a url as follows:
$route->generate(MyController::class, ['paramName' => 'value']);
But the problem with the inheritance of controllers, this bundle does not solve. Therefore, we wrote our own bundle, which solves all these tasks -
PaEndpointBundle
Bundle features:
')
- Simple controller interface - only one execute method (Request $ request): Response
- Convenient generation of url by class name - $ router-> url (SomeEndpoint :: class)
- Easy refactoring - when renaming or moving a controller, no additional actions are required, for example, changing the name of the route
- No need to specify the name of the route (but you can, if necessary)
The basic concept of a bundle is Endpoint - the entry point into the application (in the terminology of symfony, a controller with a single action). An example of a simple Endpoint:
use PaLabs\EndpointBundle\EndpointInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; class TextEndpoint implements EndpointInterface { public function routes() { return new Route('/cool_message'); } public function execute(Request $request): Response { return new Response('Hello, world'); } }
This endpoint processes requests to
your.server / cool_message and returns a response with the text 'Hello, world'.
In order for endpoint to work, you only need to register it as a service in symfony. There is no need to do anything else - the bundle will detect the endpoint itself and add its routes to the general list of routes of the application.
If you need to set your own name of the route, you can do this as follows:
public function routes() { return new EndpointRoute('my_route_name', new Route('/cool_message')); }
after which it can be used with a standard symfony router, or in templates.
Since the routes () method in endpoint is a normal class method, it can use any logic to generate routes, for example, generate routes based on some system settings, turn routes on or off as needed, create a collection of routes.
To generate urls, the
EndpointRouter class is used. Usage example:
class SomeService { protected $router; public function __construct(EndpointRouter $router) { $this->router = $router; } public function doWork() {
Even if the own name of the route was specified in TextEndpoint, $ router-> url (TextEndpoint :: class) will still work. This is achieved by caching routes. Of course, if more than one route was specified for the endpoint, it will not work to generate the url by the class name and you will have to use the name of the route.
Examples of using the bundle can be found in the
demo application .
I hope that
PaEndpointBundle or its ideas will be useful to symfony developers.