Retour sur la conférence Symfony Live 2024

Simon Jenn
22 avril 2024

L'agence Codéin est experte en développement d’applications Symfony, nous avons donc naturellement envoyé une délégation à la conférence annuelle de SensioLabs qui a lieu chaque année fin mars à Paris. Aussi, en tant que partenaire de SensioLabs nous avons décidé de sponsoriser cet événement. 

Pour rappel, SensioLabs est l’entreprise qui développe le framework libre et open source Symfony. Ses outils sont de grande qualité, ils nous permettent de développer des applications sans coût de licence. Nous pouvons nous appuyer sur la communauté pour obtenir un code en constante amélioration et évolution. Le modèle de l’open source a besoin de contributeurs et de sponsors, Codéin prend sa part et compte bien y contribuer sur le long terme. Symfony le lui rend bien ;-)

Il est important de souligner que la conférence Symfony Live 2024 était avant tout destinée à un public technique et expérimenté, principalement des développeurs. Les sessions étaient riches en contenu technique, ce qui en faisait un événement particulièrement adapté aux professionnels de ce domaine.

Avant de poursuivre, il faut noter que ce compte rendu ne se veut pas exhaustif, mais plutôt une série de notes reflétant les aspects pertinents tels que nous les avons perçus.

 

Codéin au Symfony Live 2024 à Paris

 

Session 1 : Keynote

Fabien Potencier https://twitter.com/fabpot 

Le créateur du framework Symfony a accueilli les participants, remercié les partenaires et nous a présenté la façon dont les repository de Symfony étaient conçus, découpés, gérés. 

Le dépôt principal “mono-repo” de Symfony contient des bundles/composants. Pour autant, chaque bundle est lui aussi publié sur son propre repo. Pour cela, git subtree a été  utilisé afin que le contexte des mises à jour de chaque bundle “many-repos” soit bien contextualisé dans l’évolution du dépôt principal. 

Git subtree est une alternative à submodule. Il permet une collaboration bidirectionnelle entre le dépôt principal et les sous-projets. L’historique de la période avant découpage est lui aussi conservé dans les nouveaux dépôts. Les mises à jour inter dépôts sont possibles.

La présentation est allée jusqu’à montrer les mécanismes utilisés par git pour réaliser ces découpages (méta-données, blob, hash, squash, etc…).

Fabien Potencier propose d’ailleurs un outil qui simplifie l’utilisation de git subtree : splitsh-lite afin de synchroniser automatiquement un référentiel monolithique avec des référentiels autonomes en temps réel. 

Codéin sponsor SymfonyLive 2024

Voici les slides de Fabien Potencier qui présentent ce sujet : https://speakerdeck.com/fabpot/a-monorepo-vs-manyrepos 

 

Session 2 : Applications riches en JavaScript, façon Symfony !

Kévin Dunglas https://twitter.com/dunglas

Kévin Dunglas est le co-fondateur de Les-Tilleuls.coop, fait partie de la Core team Symfony, a créé API Platform, FrankenPHP et Mercure.

Il nous a présenté des alternatives à la création de Single Page Applications (SPA) en tendant vers une approche simplifiée qui répond souvent aux besoins finaux, sans sortir l’artillerie lourde des framework JS. Et cela peut attirer des développeurs Symfo qui sont moins à l’aise avec ces derniers. Cela peut aussi simplifier la vie de certains projets : moins de compétences requises, moins de composants, etc…

Les SPA sont souvent des applications mono page, les navigateurs chargent toute l’application lors de la première visite, les interactions (données, événements, …) sont ensuite gérées entre API et des composants JS. Pour cela, l’architecture de l’application nécessite beaucoup de composants.

L’approche simplifiée met au placard les frameworks JS, et webpack n’est plus nécessaire. Plus besoin de développer d’API, l’architecture système s’en trouve simplifiée. 

Hotwired (Turbo + Stimulus) fournit des possibilités pour faire de l’interaction front sans rechargement de la page, AssetMapper peut gérer les assets. Et en général : plus besoin d’écrire de JS (uniquement twig/symfony/html) ! Les URL peuvent varier. Sans JS l’application est malgré tout servie, Les Turbo-frame permettent d’affiner le chargement de partie de pages avec des préférences de cache différentes.

SymfonyUX (cf plus bas) fournit des packages qui devraient répondre à beaucoup de problématiques dans cette approche (live components, chart.js, notify, autocomplete, …).

Le grand avantage de cette approche est aussi la simplification de la gestion du cache, du SEO. 

Cette approche est conseillée dans des projets type CMS, e-commerce, application métier “simple”.

En résumé : ce sont des parties de code HTML générées côté serveur qui sont échangées avec le client. Le DOM est modifié avec un diff en fonction des réponses reçues.

Bien entendu, l’approche plus classique garde aussi ces avantages : quand une API existe ou doit être consommée par plusieurs services, elle a lieu d’être. Les applications plus poussées ne peuvent pas entrer dans cette case.

Ensuite, Kévin nous a rappelé l'intérêt de FrankenPHP, un serveur d’application Symfony tout en un. Il sert l’application php, gère les certificats, supporte HTTP 3, permet de transformer nos applications PHP en binaires, embarque les extensions php classiques, inclut aussi Mercure (pour faire des push) et supporte Prometheus. Les performances seraient au RDV avec le mode worker (on n’a pas testé). Merci pour la contribution !

Voici les slides qu’il met à disposition : https://dunglas.dev/2024/04/front-end-application-development-symfony-styles/ 

Radical Simplicity

 

Session 3 : Vos logs méritent mieux que la config par défaut

Grégoire Pineau https://twitter.com/lyrixx 

L’objectif de ce talk est de refaire un point sur notre façon de gérer les logs dans le cadre de l’observabilité de nos applications.

Dans les bonnes pratiques recommandées, en voici une sélection : 

  • Logguer ne se limite pas à empiler des chaînes de caractères dans un fichier de logs
  • Selon le degré d’alerte ou selon le sujet, ils peuvent être envoyés à un service tiers (messagerie, centralisateur de logs, …) dans une base de données, dans un fichier ou simplement ignorés
  • Le niveau de log doit guider son lecteur dans le choix de sa réaction : de ne rien à faire, à plus rien ne marche il faut intervenir immédiatement
  • Un message de log qui n’est pas accompagné d’un contexte n’est souvent pas pertinent
  • Un message de log doit être “fixe” et unique, sans variable (qui doivent être placées dans le ‘context’)
  • Les crons/workers/processus asynchrones doivent être particulièrement loggués car il est difficile de suivre ce qu’il s’y passe
  • ProcessorInterface : le contexte d’un log doit être construit avec un serializer (et ne pas y placer un objet complexe)
  • Il existe des Processor clé en main, ex : WebProcessor qui ajoute automatiquement informations d’URL et IP source
  • Les logs doivent être organisés en channels qui est un journal de logs, il en existe par défaut, on peut en ajouter, il faut se limiter à une vingtaine de channels par application
  • Les logs sont envoyés à des tiers via des handler, dont certains sont fournis par Monolog
  • Ne pas oublier la rotation des logs quand ils sont stockés dans des fichiers et aux buffers qui pourraient bloquer une requête utilisateur en cas d’indisponibilité et de traitement synchrone
  • Un formatter permettra de modifier le format des messages de logs, passer d’une ligne à du json, etc…
  • Certains messages de logs, répétés toute la journée, mériteraient d'être écrits par intermittence (ex : dépréciations) par soucis d’économie (place ou coût saas) et lisibilité : Log Sampling
  • Les outils self-hosted pour stockage et analyse des logs : Suite Elastic ou Loki/Grafana
  • Les outils Saas pour stockage et analyse des logs : Datadog, NewRelic

Voici les slides de cette présentation : https://speakerdeck.com/lyrixx/vos-logs-meritent-mieux-que-la-config-par-defaut 

 

Session 4 : Ne pas confondre Rôle et Permission

Robin Chalas https://twitter.com/chalas_r

L'intérêt de cette conférence est de présenter les bonnes pratiques dans la création et l’utilisation des rôles et permissions d’une application Symfony.

La notion de rôle doit être associée à une fonction. Par exemple : un lecteur, un administrateur, un modérateur.
La notion de permission correspond à un agrément pour réaliser une action (lecture d’un article, modification d’un utilisateur, suppression, …).

Un rôle est composé de plusieurs permissions.

Les rôles peuvent être organisés en hiérarchie : un utilisateur qui a le rôle administrateur hérite du rôle modérateur.

La méthode hasRole détermine si un utilisateur a un rôle sans tenir compte de la hiérarchie. Il faut donc utiliser la méthode isGranted (méthode héritée du baseController). La hiérarchie est donc parcourue.

Le contrôleur n’est pas censé gérer le contrôle d’accès en comparant l’utilisateur loggé et le contenu en cours d’édition par exemple. A terme, cela peut devenir lourd et difficilement maintenable. Il devrait s’en tenir à l’utilisation d’un isGranted via les attributs.

A partir du moment où des permissions fines sont nécessaires, des stratégies avancées doivent être mises en place. Exemple : un utilisateur ne peut que modifier les articles dont il est l’auteur.

L’utilisation des attributs “IsGranted” est une première solution pour gérer le contrôle d’accès basé sur les attributs “ABAC”. C'est-à-dire que le controller ne va pas regarder le rôle de l’utisateur, mais déléguer la décision d’accès en fonction du contexte fourni dans l’attribut. Ex : l’utilisateur est l’auteur de l’article.

La solution à privilégier est le Voter. C’est une élection où des voters sont appelés pour exprimer leurs votes (abstention, oui, non). Le premier qui dit “oui” ouvre la porte.
Symfony fournit des voters en fonction des rôles : RoleVoter, ExpressionVoter. On peut développer ses voters custom.

Il est aussi possible de créer des PermissionVoter qui sont encore plus précis. A partir de sujets et d’attributs, le voteur peut donner son verdict : access_granted, access_denied.

Voici la documentation Symfony à ce sujet : https://symfony.com/doc/current/security/voters.html

Et les slides de cette session : https://slides.com/chalasr/ne-pas-confondre-role-et-permission 

 

Session 5 : Un Serializer sous stéroïdes

Baptiste Leduc https://twitter.com/Korbeil_  

Mathias Arlaud https://twitter.com/matarld

Ce talk nous a présenté des façons d’améliorer la performance de la sérialisation d'objets. La sérialisation consiste à exporter un objet dans un format exploitable et plus petit, dans l’objectif de le transporter, sauvegarder, …

Le composant TypeInfo est mis à disposition de la communauté pour intégrer des métadonnées dans la sérialisation, cela a pour intérêt de mutualiser la sérialisation tout en gardant les données spécifiques.

Les soucis de performance liés à la sérialisation sont souvent causés par la quantité de données stockées en mémoire (gros tableaux), quand on exporte des collections par exemple. Le composant JsonEncoder va encoder “petit à petit” la string. Les bundle AutoMaper et TurboSerializer sont aussi présentés (à titre expérimental à ce stade) pour améliorer significativement les performances.

Voici les slides de la session : https://slides.com/mathiasarlaud/symfony-live-un-serializer-sous-strodes

 

Session 6 : Expérience L-I-V-E (Components)

Simon André https://twitter.com/simonandre 

Simon nous a présenté des outils de l’initiative Symfony UX.

UX Icons : permet d’intégrer des icons SVG dans un catalogue très fourni

Live components : sortis au même moment que les twig component.

Les Twig Component sont constitués d’un template et d’une classe PHP. Ils peuvent s’intégrer avec une syntaxe HTML <twig>. Les développeurs front sont autonomes pour définir les variables nécessaires aux templates.

Les Live Components reprennent ce principe, il suffit de transformer les twig component en utilisant l’attribut “AsLiveComponent” dans sa classe. Le composant devient “live” pour transmettre les changements d'état et créer de l’interaction.

Les live props permettent de lier un attribut à un champ de formulaire par exemple. Une mise à jour côté client est immédiatement mise à jour côté serveur.

Les Live Actions : un bouton dans le composant déclenche une action (via Stimulus) par un appel ajax qui fera appel à une méthode de notre classe PHP.

Les Live Events : le serveur peut écouter des événements, mais le serveur peut aussi envoyer des événements vers le client.

Le Live Loading : pour appeler une fonction toutes les x secondes (pour un live score par exemple), ou pour rendre un composant asynchrone (lazy loading).

Il suffit de require symfony/ux-live-component pour que la couche JS et la configuration soit déployée (grace à Symfony Flex, AssetMapper).

Ils sont très bien intégrés avec : les Symfony Form (entre autres pour la validation),la security, l’AssetMapper, le profiler, les tests.

Les composants peuvent avoir des routes dédiées. Il est aussi possible de modifier en live l’url pour retrouver l’état de la page plus tard (mise en favoris, partage d’URL).

L’approche composant permet d’isoler la fonctionnalité. Les composants peuvent contenir d’autres composants.

Il est possible d’intégrer des live components par petites touches dans nos applications. 

Beaucoup de démonstrations sont disponibles ici : https://ux.symfony.com/live-component#demo 

Il est possible de ne pas écrire une seule ligne de javascript, ce qui peut être un atout pour certaines équipes.

En termes de performance, il n’y a pas de souci à se faire (cf benchmark).

 

Session 7 : Comment tester une API externe en ayant 0 Mocks ?

Ezzine Imen https://twitter.com/imenezzine1

Il est toujours complexe de développer des applications dépendantes d’API tierce car nous sommes dépendant de leurs accessibilités, et les réponses peuvent varier d’un moment à l’autre ce qui complique les tests.

Une solution pour pallier ces contraintes est de mettre en place des mocks pour obtenir des réponses systématiques et stables. Cependant, leur maintenance peut s’avérer coûteuse. De plus, il est difficile d’anticiper tous les cas de figures de réponses car l’API tierce ne nous appartient pas systématiquement.

Imen Ezzine a présenté une alternative sans mock, tout en restant dans des conditions acceptables.

Des VCR (= Video Cassette Recorder) peuvent être utilisés pour cela : PHP-VCR, Guzzle VCR, PHP-HTTP VCR Plugin.

Ces outils effectuent un premier appel à l’API, enregistrent la réponse, et la fournissent aux appels suivants. Les données sont stockées généralement dans des fichiers, on utilise un client VCR pour faire les appels. Les méthodes classiques (file_get_contents, curl, …) sont automatiquement surchargées pour passer les appels via le VCR.

Voici les slides : https://slides.com/imenezzine/symfony-live-2024 

 

Session 8 : Lightning talks

Pendant cette session “libre”, deux sujets sont à retenir.

Une sensibilisation à l’over engineering : créer des applications avec des fonctionnalités plus que nécessaires les rendent inutilement complexes, potentiellement plus lourdes, et augmente le risque de failles de sécurité. Nous sommes souvent tentés d’inclure les dernières bibliothèques, pour utiliser l’un ou l’autre composant pour gagner du temps à court terme.

Ajouter des stack techniques nécessite des équipes à plusieurs profils. L’hétérogénéité des équipes ne pourra peut-être pas être maintenue dans le futur.

Voici d’autres exemples qui devraient nous interroger : 

  • Rendre tous les composants de notre application réutilisables, puis les adapter sans cesse pour répondre aux besoins spécifiques, pour devenir complexes et difficiles à maintenir. Un code non compris par les développeurs risque d’en devenir inmaintenable.
  • Abuser de l’abstraction : il faut se poser la question si cela à un intérêt pour les tests, si les services doivent répondre à un contrat, …. au risque de complexifier inutilement
  • Céder à la performance : est-elle toujours si importante, ressentie ? si non, optez pour la méthode la plus simple

Une présentation du task runner Castor (un phar) : une alternative à nos makefile, écrite en PHP avec autocomplétion dans le terminal et l’IDE. A utiliser dans nos CI, environnements de développement, On peut le compiler pour le déployer facilement. Il est aussi capable de paralléliser des process.

La doc : https://castor.jolicode.com/ 

Les slides de la présentation de Castor : https://speakerdeck.com/lyrixx/castor-symfony-live-2024-paris

 

Session 9 : Les nouveautés de Symfony 7.1

Nicolas Grekas https://twitter.com/nicolasgrekas 

Nicolas Grekas, contributeur principal de Symfony, nous a présenté les nouveautés de Symfony 7.1 après avoir rappelé à l’audience de s’engager “go beyond, composer update and contribute !” et quelques bonnes pratiques.

Stratégies sur les mises à jours : 

  • Recommandation de faire un composer update tous les mois et tous les 6 mois en modifiant le composer.json sur nos applications. Il n’y a pas de risques car il s’agit de migration mineures avec une garantie de compatibilité (uniquement dépréciations ou nouvelles fonctionnalités ajoutées). Cela permet de passer les versions majeures plus facilement.
  • Il n’est pas nécessaire, ni recommandé, de se cantonner aux versions LTS, on ne devrait pas attendre pour mettre à jour. La LTS tient 3 ans, alors que “la pas LTS” avec composer update tient 7 ans. 

Quelques nouveautés :

  • Symfony 5 sera compatible avec PHP 8.4
  • TypeInfo : remplace propertyInfo pour introspection des objets PHP, utile dans les serializer
  • Emoji : un composant à part pour intégrer les emoji avec une variante par langue
  • Notifier : avec des bridges pour envoyer des notifications sur slack, twitter, outils locaux (pour éviter les SDK des providers), etc…
  • Mailer : avec des bridges qui permettent de traiter les retours d’envoie d’email par exemple, en fonction du fournisseur
    • DependencyInjection : Attribut “Lazy” pour ne charger la dépendance que si elle est utilisée, 
    • URLencode : pour encoder des URL dans les variables d’environnement (quand on veut par exemple composer des variables d’environnement avec d’autres variables d’environnement)
    • Autowireinline : pour créer des client http directement dans le code à la place de le faire dans la config avec des déclarations scopées
  • Profiler : un moteur de recherche par mots clés dans le profiler 
  • HttpKernel : pouvoir traiter les querystring boolean en vrai boolean (et plus en chaine de caractère “true”)
  • Twig Filter emojify : pour traduire les shortcodes en emoji

 

Session 10 : Petite thérapie de couple : je vous apprends à aimer le front-end

Matheo Daninos https://twitter.com/matheodaninos

Matheo a fait une démonstration d’une création d’une application qui diffuse des radios sous forme de galerie. Le choix est porté sur une page composée de composants indépendants. Cela permet d’avoir du code réutilisable sur des pages qui nécessitent les mêmes fonctionnalités, sans dupliquer le code back (controller) qui doit envoyer des variables en fonction du contexte. Dans cet exemple, une radio est un composant. Chaque composant a des states (play, pause), des props (nom de la radio, vignette).

Les composants sont des services qui peuvent appeler d’autres services. Le contrôleur est cantonné à traiter la request et la response, sans se soucier des variables nécessaires aux templates.

Il est aussi possible de créer des Anonymous Component qui sont constitués uniquement d’un template sans classe PHP.

SymfonyUI fournit des composants prêt à l’emploi, à l’image d’un design system.

StimulusBundle : intégration de la librairie Stimulus pour revenir aux bases de Javascript, c'est- à dire ajouter du dynamisme à de l’HTML. Il est possible d’écrire les contrôleurs Stimulus pour dynamiser le front.

Les LiveComponents peuvent remplacer les contrôleurs Stimulus quand on a besoin d'interagir avec des données côté serveur.

TurboBundle : pour transformer sa page en SPA. Il observe la page, récupère les événements utilisateurs (click), va faire la requête vers le back, et va merger la réponse reçue avec le dom actuel sans recharger toute la page.

Turbo8 : possibilité de faire des turboframe pour maintenir des parties de la page indépendamment du reste. Par exemple pouvoir continuer à écouter la radio au changement de page, et tout cela sans écrire de javascript.

TurboStream : un controller Symfony va envoyer des request en push client au format stream qui va déclencher des replace en front sur des composants, encore sans javascript.

Les slides : https://github.com/WebMamba/symfony-live-2024 

Matheo Daninos

 

Session 11 : L'instabilité de nos tests nous empêche de délivrer

Sofia Lescano https://twitter.com/SofLesc 

Sofia a fait un talk au sujet des tests. 

Un test peu fiable, dit “Flaky” : ce test donne des résultats aléatoires sans modification de code. Cela provoque des incertitudes, frustrations et retarde les livraisons. Cela noie aussi les autres résultats de tests qui devraient nous alerter.

Ex : des tests passés sur la date d’aujourd’hui (qui change tous les jours), des tests dépendants du délai d’attente (qui peut varier), des tests qui dépendent de services tiers dont nous ne maîtrisons pas les retours.

Des outils permettent de détecter ces flaky tests : Allure, CricleCI . Des tableaux de bord permettent de différencier un faux négatif d’un vrai négatif.

Les slides : c'est par ici !

Sofia Lescano

 

Session 12 : De Web App à Progressive Web App

Florent Morselli  https://twitter.com/FlorentMorselli

Ce talk a vocation à nous rappeler que nous pouvons transformer nos applications web en Progressive Web App “PWA”.

Une PWA est une application web qui peut être utilisée comme une application native sur les plateformes IOS, Android, etc…

Le PWABundle permet de transformer la web app en PWA. Il permet de mettre en cache des asset afin de pouvoir utiliser l’application hors réseau, de mettre en attente des synchronisations vers des API en fonction du statut de la connexion.

Les PWA sont indépendantes des App Stores. On peut malgré tout les packer pour les livrer dessus, mais attention à la dépendance.

Slides : https://github.com/Spomky/SymfonyLive-2024/blob/main/PWA%20-%20SymfonyLive%202024.pptx 

 

Session 13 : CQRS/ES avec Symfony, c’est (trop) bien !

Jérémy Romey https://twitter.com/jeremyFreeAgent

Cette présentation décrit la façon de réaliser une application CQRS/Event Sourcing avec Symfony qui simplifie le process. 

CQRS : séparer une application en deux, une structure pour la lecture, une pour l’écriture

ES, Event Sourcing : série d'événements sur lesquels on ne peut pas revenir en arrière pour réécrire l’histoire.

L’idée est de savoir dans quel état est une entité à un moment donné. Par exemple, la couleur de la voiture à une date donnée, et la couleur de la voiture à l’instant T. Pour cela, plutôt que de changer les propriétés de l’objet, on va enregistrer son changement d’état. On enregistre donc des événements.

Les Policy permettent de réagir à des événements : à un changement d’état je réalise cette commande.

L’Aggregate est un cluster d'objets qui garantit la cohérence métier.

L’Entity a un cycle de vie.

Les événements stockés en base stockent les données : identifiant de l’événement, son nom, son aggregate (quel type), la datetime, la donnée, le contexte du changement (quel user par exemple).

Dans cette pratique, nous pouvons rajouter des exceptions métier : on ne peut pas changer de couleur de la voiture plus de deux fois.

Slides : https://speakerdeck.com/jeremyfreeagent/es-avec-symfony-cest-trop-bien 

CQRS/ES

 

Session 14 : Introduction au Continuous Profiling

Thomas di Luccio https://twitter.com/zenhysteria

Thomas de PlatformSH et blackfireio nous a parlé d’observabilité. L’observabilité permet de mesurer la performance de l’application, son infrastructure et la contrôler dans la durée.

Voici deux approches complémentaires.

L’observabilité déterministe : plusieurs mesures (temps, cpu, mémoire, etc…) avec mise en évidence des chemins critiques. Blackfire permet de présenter ces mesures de façon habile pour identifier les goulots d’étranglement. Les développeurs peuvent donc s’appliquer à améliorer la performance de certaines briques sans connaître l’intégralité de l’application. Nous pourrons aussi comparer les performances d’une version à l’autre pour valider des améliorations.

Continuous Profiling : mesurer à un instant donné toute l’activité du serveur. En sortie nous n’avons plus une timeline mais le poids des activités à des moments donnés et nous pouvons mesurer leur consommation : ce contrôleur consomme la plus grande partie des ressources car il est souvent utilisé. On ne peut donc pas comparer deux périodes. L’information est fiable si l’utilisation de l’application est représentative.

Voici les slides : https://speakerdeck.com/thomasdiluccio/introduction-to-continuous-profiling 

 

Session 15 : Faites plus avec moins de code grâce aux attributs PHP

Jérôme Tamarelle https://twitter.com/GromNaN

 

Pour cette dernière présentation, Jérôme de MongoDB nous parle des Attributs qui sont utilisables depuis PHP8. Ces attributs permettent d’avoir un code plus compact et plus efficace.

Les attributs sont optionnels.

Voici quelques attributs qui améliorent et simplifient notre code :

  • Override : permet de signaler que nous surchargeons une méthode de la classe parente. Une alerte sera levée si la méthode parente est modifiée ou supprimée (avant cela n’avait aucune conséquence)
  • Deprecated : génère des warnings quand le code est utilisé
  • ArrayShape : permet de définir la structure d’un tableau associatif afin d’avoir de l’autocomplétion dans nos IDE (clé et valeur typée).
  • \Attribute : permet de distinguer une classe utilisable comme attribut
  • ORM\Entity : remplace les annotations doctrine pour identifier les entités
  • ORM\Field : pour les champs, le type n’est plus nécessaire à spécifier car il sera déduit du typage
  • Assert\... : pour les validations
  • Assert\Collections : pour typer les éléments de la collection
  • Tous les attributs qui commencent par “As” servent à l’autoconfiguration (pour éviter les fichiers de configuration avec l’injection et évite l’autowire).
  • Route : évite le fichier de routing
  • AsDecorator, AsEventListener : là aussi pour éviter de l’écrire en yml et simplifier aussi notre code (moins de méthodes à surcharger)
  • Autoconfigure, AutoconfigureTag : au niveau de l’interface pour définir le tag appliqué à toutes les classes qui instancient l’interface, et pas besoin de nommer le tag car il prendra le nom de la classe par défaut
  • AutowireIterator : permet de récupérer toutes les classes taggées (qui instancient l’interface)
  • AutowireCallable : permet d’inclure une méthode d’un service uniquement pour l’appeler dans un autre service/contrôleur. Utile pour mocker dans les tests.
  • Target : pour passer des httpclient particulier à la place du défaut par exemple
  • TestWith : pour définir des données de tests dans phpUnit
  • AsTiwgFunction : pour créer des fonctions filters dans twig de façon plus simple (sans étendre Twig Extention)

Bonnes pratiques : 

  • un attribut par ligne avec un dièse à chaque ligne
  • le nommage 
  • mettre tous les champs en public, économiser les getter setters pour ne pas mettre de métier dans les entités
  • mettre la définition des routes dans les contrôleurs et plus dans le routing.yml pour centraliser les données, si on veut le détail, on peut utiliser le debug:router plutôt que le code source
  • de façon générale, faire moins de config et mettre tout le contexte dans le code via les attributs
  • la migration des annotations est assez simple car les noms sont grosso modo les mêmes

Rector est un outil qui va migrer le code pour ne pas avoir à le faire à la main.

Les slides : https://jerome.tamarelle.net/slides/2024-03-29-SymfonyLiveParis2024-Attributs.pdf 

À la recherche d'une nouvelle opportunité ? Voir toutes les offres
Découvrez quelques uns de nos projets Symfony Voir les projets

A lire aussi

Notre point de vue technique sur la DXP Ibexa
Quelles solutions techniques pour améliorer la performance de votre site web ?
Voir tous les articles