Je suis dĂ©veloppeuse PHP/Symfony depuis prĂšs de 10 ans, et au cours de mes missions jâai pu tester, expĂ©rimenter, et dĂ©couvrir diffĂ©rentes architectures et design patterns en entreprise. J'ai vu du bon, j'ai vu du passable, et j'ai aussi parfois ouvert les portes de l'enfer. De ces expĂ©riences, j'ai dĂ©cidĂ© de recenser le pire, et je vous propose dans cet article le top 5 des erreurs quâil faut Ă tout prix Ă©viter sous Symfony !
#5 Faire une librairie, alors quâil sâagit dâun bundle
Combien de fois ai-je vu des soi-disant librairies qui, n'en étant pas (vous allez comprendre ce que j'entends par là trÚs vite), posaient des soucis de maintenabilité sur les projets Symfony ? La réponse est : beaucoup trop.
Tout d'abord revenons sur le vocabulaire : une librairie est un ensemble de code destinĂ© Ă ĂȘtre rĂ©utilisĂ©, qui fournit des outils pour rĂ©duire le temps de dĂ©veloppement. Il peut ĂȘtre normal, vu cette dĂ©finition, de vouloir en faire avec des composants Symfony.
Le seul hic c'est que dans lâĂ©cosystĂšme Symfony... il n'y a pas de librairies, il n'y a que des composants ou des bundles. Je rĂ©pĂšte donc : les librairies dites Symfony sont inexistantes ! Notons toutefois qu'il peut bien y avoir des librairies PHP.
Si on fait une librairire qui utilise des composants Symfony (qui aura sûrement besoin d'une configuration), alors lors d'une mise à jour de la librairie sur le projet on s'expose à la fois à des bugs difficilement identifiables mais aussi au fait de rendre la configuration illisible.
Alors que faire un bundle permet d'utiliser toutes les possibilitĂ©s quâoffre le framework comme gĂ©rer la configuration ou utiliser directement les services sans avoir besoin de les dĂ©clarer.
Moralité : que ce soit à cause de la sémantique ou de la pratique, faites des bundles si vous avez des composants Symfony !
#4 Les librairies partagées
On pourrait croire que câest une bonne idĂ©e quand dans plusieurs projets nous avons les mĂȘmes classes. On se dit que la duplication de code câest mal, qu'on a la mĂȘme unicitĂ© sur tous les projets et quâon nâa quâĂ tester quâune seule fois le code.
Sur le papier, ça passe. Dans les faits, si on nâest pas rigoureux, cela peut vite ressembler Ă lâenfer.
Prenons un exemple concret : vous avez plusieurs services qui utilisent la mĂȘme librairie, et celle-ci nâa pas de release.
Un développeur travaille sur le service A qui utilise la library Tools pour la feature 01. Il a eu besoin de modifier cette librairie, et ce code a été mergé sur la branche principale.
Mais ce dĂ©veloppeur n'a pas dĂ©tectĂ© que sa modification a créé un break change inintentionnel sur le Service B, et comme la librairie nâa pas Ă©tĂ© mise Ă jour sur celui-ci, c'est restĂ© invisible.
Un autre développeur travaille en parallÚle sur, justement, ce Service B et a aussi besoin de modifier cette librairie. Quand il va faire sa branche sur la librairie, cela sera à partir de la branche principale, avec la modification pour la feature 01. Quand la librairie sera mise à jour pour tester la branche spécifique, il y aura une erreur, dont la raison demeurera complÚtement opaque pour le deuxiÚme développeur...
Cela fait perdre du temps pour dĂ©bugger, car ça implique de solliciter toute son Ă©quipe, pour identifier le dĂ©veloppeur responsable du break change et corriger ce qui doit l'ĂȘtre.
S'il y a une bonne communication dans votre Ă©quipe et avec les autres Ă©quipes, un mĂȘme processus rigoureux, ou un versionning fait dans les rĂšgles de lâart, vous pourrez limiter les impacts de ce genre d'erreur.
#3 Ne pas faire les mises Ă jour Symfony
Qui nâa pas dĂ©jĂ eu Ă travailler sur du code legacy en Symfony dans une vieille version, dont la mise Ă jour est devenue plus difficile et coĂ»teuse au fur et Ă mesure du temps qui passe ?
Le framework nâest pas mis Ă jour rĂ©guliĂšrement que pour des nouvelles fonctionnalitĂ©s, il l'est aussi pour corriger des bugs qui peuvent ĂȘtre relatifs Ă la sĂ©curitĂ©. Cela veut dire qu'en ignorant une ou plusieurs mises Ă jour, vous pouvez laisser des failles sur votre application.
Aussi, les versions de Symfony sont liées à des versions de PHP. Vous ne pourrez par exemple pas monter votre version de PHP sur le serveur si vous avez une vieille application qui tourne sur du Symfony 3/PHP 7.
Faire rĂ©guliĂšrement les montĂ©es de versions de Symfony en enlevant progressivement les deprecated Ă©vitera les surprises lors dâune montĂ©e majeure de version.
Attention toutefois, car paradoxalement faire trop rapidement une mise Ă jour Symfony est aussi une erreur.
Rares sont les projets qui nâutilisent pas de bundles externes, et quand il sâagit dâune montĂ©e de version majeure, il faut attendre que ceux-ci proposent leur propre mise Ă jour.
MĂȘme si de nos jours les releases Symfony sont globalement stables, attendre un petit peu pour ĂȘtre sĂ»r quâil nây ait pas de bugs peut ĂȘtre salutaire.
#2 TROP utiliser les Event Listeners
Je suis la premiÚre à aimer utiliser les listeners : ça me permet de mettre en place une action commune pour un événement particulier assez facilement.
Mais ça peut vite devenir une usine à gaz difficilement maintenable pour toute nouvelle personne arrivant sur le projet.
Les listeners sont souvent invisibles dans le code, dispersĂ©s entre le code source et les bundles, pouvant ĂȘtre dĂ©clenchĂ©s trĂšs facilement si l'Ă©vĂ©nement est rĂ©current. Les risques sont dâavoir des listeners se marchant sur les pieds (par exemple un listener pouvant impacter le comportement d'un deuxiĂšme) ou de plomber les performances par des appels trop frĂ©quents. Blackfire peut ĂȘtre votre ami dans ce cas-lĂ avec le metric symfony.events
.
GrĂące Ă la commande bin/console debug:event-dispatcher
ou dans le profiler, il est facile dâavoir la liste des classes, de vĂ©rifier qu'un listener existant ne peut pas ĂȘtre enrichi avant d'en crĂ©er un autre et surtout de debugger.
#1 Utiliser API Platform aveuglément
API Platform permet de crĂ©er rapidement des APIs et cela permet de gagner un temps incroyable en dĂ©but de projet. Malheureusement, le coĂ»t de dĂ©veloppement et de maintien vient plus tard et peut ĂȘtre faramineux.
Si votre besoin est trĂšs spĂ©cifique et demande plus que des CRUD basiques, cela peut vite devenir trĂšs lourd : besoin de faire des hacks dans tous les sens, dâoverride des classes, et si vous avez besoin dâune serialization un peu gourmande, vos tirs blackfire vous feront perdre de la tĂȘte. Pour lâavoir vu et expĂ©rimentĂ©, il faut ensuite dĂ©ployer une Ă©nergie folle et faire appel Ă son ingĂ©niositĂ© pour passer outres toutes ces problĂ©matiques.
API Platform propose rĂ©guliĂšrement des mises Ă jour pour amĂ©liorer sa performance, pourtant je reste convaincue de ne pas lâutiliser si le projet est un peu plus complexe.
En fonction de votre besoin, il faut rĂ©flĂ©chir entre utiliser cet outil ou faire soi-mĂȘme son API. FOSRestBundle vous permettra dâĂȘtre indĂ©pendant sur les actions que doivent faire vos routes, sans code magique, ce qui vous permettra de maĂźtriser la rĂ©silience et la performance de votre application.
Conclusion
Ce top est propre Ă mon expĂ©rience, et avec de la chance, je nâai sĂ»rement pas tout vu.
Et vous, quelles erreurs avez-vous déjà vues ?