Annotations bring coupling as shown in Matthias Noback’s book on “A year with Symfony” and elsewhere in many blog posts around. You realize this too late if you are a newcomer because the documentation and many bundles assumed sometime ago that annotations was a good idea for automating stuff. This is the magic that Symfony in its beginnings set out itself to pursue but did not stick to as we are seeing lately in some developments. Easy of use can be sometimes a trap to add too much magic and blur the view of developers to use a library or framework.
Thanks to some efforts however there is a way in which you can pull your project out of annotations. One of them is using the doctrine bundle built-in capability to export mapping to yaml or other formats. The exporting seldom needs adjustments and even though some say it could be broken or lack some features, pretty much saves you a lot of time when you are doing the move with minor or no adjustments at all.
For instance if you have a
Vendor\CoreBundle
you can just issue this command:
php app/console doctrine:mapping:import "VendorCoreBundle" yml |
The only thing with the output is that you will have to remove the indexes that it created and lifecyclecallbacks if you like to be clean and did not have anything specified in those fields.
It however generates a complete specification which helps you don’t miss anything:
// ... targetEntity: VendorUsers cascade: { } fetch: LAZY mappedBy: null inversedBy: null joinColumns: locked_by_id: referencedColumnName: id orphanRemoval: false // ... |
That is for mapping, but what about annotations. Well simply just install the bundle https://github.com/sed-szeged/SedRouteExporterBundle and run:
mkdir builds-output php app/console sed:router:export --format yaml --output builds-output |
The output is clogged into a single
routing.yml
file but it is easily split and cleaned up. The specification is also complete on the output:
user_lock: path: /users/lock defaults: { _controller: 'Vendor\Bundle\CoreBundle\Controller\UserController::lock' } options: { compiler_class: Symfony\Component\Routing\RouteCompiler } |
Now your controllers will look much cleaner, you can actually go Controllers as Services and then have actual tests that cleanly tests part of your controllers at least. Definitely this will increase the quality of the code of your project because you are decoupling not only mapping, but routing, and others as well as you don’t need necessarily tools to convert but they speed up the process in converting something like this:
/** * @Cache(expires="tomorrow") * @Method(...) * @Template() * @ParamConverter() * @Route("some_route_here") * @Secure(roles="ROLE_USER") * @RunAs(roles="ROLE_PRIVATE_SERVICE") * @InjectParams({ * "em" = @Inject("doctrine.entity_manager") * }) */ */ |
Which is madness and that is just a quick invented example on how some projects end up. The conversion will heal you and your team.