Symfony ExpressionLanguage : Comment utiliser ce composant ?
Le composant Symfony ExpressionLanguage : qu'est-ce que c'est ? Quand et comment l'utiliser ? Comment créer des expressions lors de cas plus complexes ?
Sommaire
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 !
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 !
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.
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.
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.
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.
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 ?
Auteur(s)
Marianne Joseph-GĂ©hannin
Architecte applicatif et lead dĂ©veloppeuse PHP/Symfony đŠ
Vous souhaitez en savoir plus sur le sujet ?
Organisons un Ă©change !
Notre équipe d'experts répond à toutes vos questions.
Nous contacterDĂ©couvrez nos autres contenus dans le mĂȘme thĂšme
Le composant Symfony ExpressionLanguage : qu'est-ce que c'est ? Quand et comment l'utiliser ? Comment créer des expressions lors de cas plus complexes ?
Découvrez comment réaliser du typage générique en PHP : introduction et définition du concept, conseils et explications pas-à -pas de cas pratique.
Découvrez un cas d'usage d'intégration d'un CRM avec une application e-commerce, en asynchrone, avec Hubspot et RabbitMQ