Ce que vous devez retenir de SymfonyWorld 2020 1/2

Ce que vous devez retenir de SymfonyWorld 2020 1/2

Le rendez-vous annuel majeur de l’écosystème Symfony avait lieu ces jeudi 3 et vendredi 4 décembre et nous y étions.

La SymfonyCon ne pouvant se dérouler en physique cette année, elle s’est donc tenue en ligne, sous le nom de SymfonyWorld. Les talks ont été diffusés mondialement dans 2 fuseaux horaires.

Cette conférence était d’ailleurs l’occasion parfaite pour célébrer 4 grands événements :

  • les 15 ans du framework ;
  • les 25 ans de PHP ;
  • la sortie de PHP 8 ;
  • et enfin la sortie de Symfony 5.2 !

Cet article présente les sujets qui nous ont le plus marqué sur la première journée de conférences. La seconde journée sera traitée dans un prochain article. Bonne lecture !

L’annonce de Symfony UX

Annoncée durant la keynote, Symfony UX est une initiative pour faciliter l’intégration d’applications Web riches. Elle a été menée par Titouan Galopin, nouvellement intégré à la Core Team pour l’occasion.

Symfony UX

Pour créer une application riche, nous avions jusqu’à maintenant deux options : fournir directement du HTML et l’améliorer avec du Vanilla JS, jQuery, React, …, ou alors exposer une API et construire une SPA.

Symfony UX essaie de proposer une nouvelle alternative qui se situe au milieu de ces deux paradigmes. Son utilisation se veut simple : nous continuons d’écrire du HTML avec Twig de manière accessible. Celui-ci sera alors amélioré progressivement avec des composants fournis par la communauté : Chartsjs, Cropperjs, Dropzone, LazyImage pour commencer.

L’installation se fait avec nos outils habituels composer et yarn. Symfony Flex s’occupe du reste.

Pour améliorer l’expérience utilisateur de nos sites, il faut parfois changer un type de champ dans un formulaire, ajouter un attribut sur un élément du DOM, etc. Avec Symfony UX, très peu de changements seront nécessaires dans notre code !

Voici un exemple pour charger les images en asynchrone, tout en affichant une forme diffuse avant son chargement :

<img
    src="{{ data_uri_thumbnail('public/image/large.png', 100, 75) }}"
    data-controller="@symfony/ux-lazy-image/lazy-image"
    data-hd-src="{{ asset('image/large.png') }}"

    {# Using BlurHash, the size is required to determine the space that the image will occupy #}
    width="200"
    height="150"
/>

Blur Hash dans Symfony UX

Une autre nouveauté : le rechargement partiel de page (à la TurboLink). Pourquoi recharger toute la page, les menus, le CSS, le JavaScript quand on peut uniquement mettre à jour le contenu qui change ? Grâce à swup et son intégration dans Symfony UX, c’est maintenant possible.

Symfony s’appuie sur stimulusjs, un framework JavaScript très léger pour organiser notre code JS, et publier des composants réutilisables. Un nouveau bridge a été créé pour l’occasion.

Découpler une application avec Symfony Messenger

David Buchmann nous a présenté le composant Messenger et son fonctionnement en reprenant tous les concepts les plus importants :

  • Le Message, un objet qui va contenir des informations (si nécessaire) et qui sera sérialisé par Messenger ;
  • Les tampons, nommés « Stamp » dans Messenger, qui vont permettre d’apporter des métadonnées au Message, ils pourront être réutilisés par le Transport ou les Middlewares ;
  • Le Handler, c’est lui qui recevra le message et le traitera ;
  • Le Transport correspond au logiciel que vous utilisez pour transporter vos messages, selon votre configuration. Cela peut être Doctrine, Redis, AMQP, SQS ou encore Kafka.

On peut noter quelques astuces pour avoir des workers efficaces :

  • Utilisation de systemd / supervisord pour gérer le restart et les logs de vos workers ;
  • Avoir une limite de temps et/ou de mémoire sur vos workers pour les relancer automatiquement ;
  • Et penser à relancer ces workers à chaque déploiement !

Enfin, pour finir son talk, il nous a montré quelques cas réels d’extensions de Messenger dans une application sur laquelle il travaille. On peut noter par exemple :

  • Middleware Transaction ID, un service qui va lire tous les Message qui passent dans Messenger et qui va leur attribuer un ID unique via un Stamp ; cela permettra de suivre ce message entre les différentes couches applicatives de son projet ;
  • Dans AMQP, nous pouvons donner une priorité à nos messages. Nous avons vu que grâce à un middleware AmqpStamp, nous pouvons régler cette priorité et bien d’autres métadonnées liées à AMQP ;
  • Enfin nous avons pu voir un middleware Deduplicate, qui va générer un hash unique pour tous les messages et y attacher un lock pour empêcher un message identique d’être envoyé une seconde fois.

Du nouveau dans API Platform

Kévin Dunglas a commencé par une rapide présentation d’API Platform. Ce qui nous a le plus marqué, c’est qu’il a présenté APIP comme un composant pour exposer des POPO via une API, et non pas des entités Doctrine.

Les ressources APIP exposées doivent être ce qu’expose l’API. Cela peut toujours être une entité directement, ou un model Doctrine ODM. Cependant à la place d’utiliser des inputs ou outputs, il est préférable d’exposer directement un DTO, puis d’écrire son propre DataProvider ou DataPersister.

Il nous a ensuite listé les nouveautés d’API Platform !

Sur le core d’API Platform (composant PHP) :

  • Support de PHP 8 : nous pouvons configurer les ressources avec les attributes de PHP 8 ;
  • Configuration globale : nous pouvons configurer toutes les ressources d’un coup. Par exemple, désactiver tous les DELETE. Bien entendu, chaque ressource peut surcharger la configuration globale ;
  • Access Control pour les propriétés : nous pouvons protéger leur écriture grâce au composant Security ;
  • Support natif du protocole Vulcain.

Sur la génération de code JavaScript :

L’édition « Docker API Platform » a remplacé toute sa stack serveur web (NGINX, Mercure, Vulcain, …) par le serveur web caddy.

APIP 2.6

Enfin, APIP version 2.6 alpha vient de sortir ! La version 2.7 sera surement la dernière de la branche 2.x, car la version 3 a été annoncée. Elle sera la même release que la version 2.7 mais sans les couches de compatibilité. APIP suit ainsi la même logique que Symfony. Nous avons aussi appris que la version 3 sera compatible avec PHP >=8.0 uniquement.

Lock & Semaphore

Jérémy Derussé a donné bon nombre de bonnes pratiques sur l’utilisation du composant Lock, ainsi que les pièges à éviter. Nous vous invitons a regarder ses slides. Il a aussi introduit de nouveaux concepts disponibles avec Symfony 5.2 :

  • Des locks partagés : Un service qui lock en lecture / écriture (par exemple, celui qui édite la facture), et les autres services lockent en lecture seulement. Ces derniers ne peuvent pas se bloquer entre eux ;
  • Le composant sémaphore : Une sémaphore est une version plus puissante qu’un lock dans le sens où nous pouvons autoriser jusqu’à N processus à bloquer une ressource. Nous pouvons dire qu’un lock est une sémaphore quand N=1.

Le composant Console

Christopher Hertel nous a parlé du composant Console, ses bonnes pratiques, ainsi que les nouveautés de ce dernier. Nous avons beaucoup aimé son utilisation, car nous l’utilisons de la même manière. Voici ce que nous pouvons retenir :

  • Utiliser la class ApplicationTester pour tester son application avec le KernelTestCase;
  • Placer votre code qui interagit avec l’utilisateur dans la méthode Command::interact() au lieu de execute() ;
  • Utiliser les events. Pour, par exemple, logger ou monitorer vos commandes ;
  • Les commandes sont des entry points, comme les controllers, donc il ne faut pas mettre de logique dedans ;
  • Ne pas utiliser $output->printLn() mais le logger à la place pour les commandes de type background (worker, cron) ;
  • Jouer avec les niveaux de verbosité (Verbosity Level: -v, -vv, -vvv) ;
  • SymfonyStyle : un wrapper au dessus de l’Input et l’Ouput ;
  • L’utilisation des sections pour séparer, par exemple une ProgressBar et des messages d’erreur ;
  • Une méthodologie à base de callback pour mettre à jour une ProgressBar lors d’un import par exemple. Combiné avec les sections, ce système est vraiment pratique ;
  • La gestion du curseur depuis PHP : Nous n’avons pas encore de cas d’usage, mais David s’est amusé à refaire le fameux jeu vidéo snake avec Symfony ;
  • Gestion des signaux (SIGINT, etc) ;
  • Gestion de “true color” : on peut maintenant afficher des images avec la Console de Symfony.

Elasticsearch et Symfony

Damien a eu l’opportunité de partager son expérience sur l’implémentation d’Elasticsearch dans un projet Symfony.

Pour résumer, sa stack idéale est la suivante :

  • Utiliser du YAML pour la configuration des mappings (JSON n’est pas fait pour les humains) ;
  • Utiliser Elastica pour la couche objet PHP et ne pas avoir à écrire son Query DSL en tableau associatif (dette visuelle, fragilité, manque de complétion automatique, …) ;
  • Faire d’Elastica un ODM pour permettre d’indexer des DTO et les récupérer dans les résultats de recherche ;
  • Versionner les indexes ;
  • Ne jamais utiliser de mapping dynamique ;
  • Monitorer ou ne pas héberger soi-même Elasticsearch.

Ce sujet fera prochainement l’objet d’une série de publications sur ce blog tant il est vaste et important. En attendant, nous maintenons une librairie qui implémente ces bonnes pratiques : Elastically !

PHP + Minecraft

Thomas Berends nous a montré qu’il existait des outils pour modifier le monde de Minecraft via PHP !

La présentation était très complète et nous avons beaucoup aimé en savoir plus sur les objets internes du jeu. Cependant les cas d’utilisation vont être compliqués à trouver sur nos projets !

Très bel exemple en tout cas de fusion entre deux passions : sky is the limit !

Minecraft PHP

Thomas a publié un package PHP avec ses expérimentations et nous a indiqué les packages populaires si vous souhaitez contrôler Minecraft via PHP :

Bravo à Thomas, pour qui c’était la première conférence en tant que speaker ! 👏

Symfony meets Cypress – E2E testing for symfony developers

Ramona Schwering nous a fait une superbe démo de Cypress, un outil de test fonctionnel E2E (End To End, pour tester aussi bien le backend que le frontend) très complet.

Ces tests sont en général très peu robustes, complexes à écrire et à débugger. Nous utilisons souvent Jest et Puppeteer par exemple, ou Panther, ou encore Selenium. C’est pourquoi la démo de Cypress nous a marqué : tout à l’air simple et surtout, il est possible de suivre le test, étape par étape, dans un navigateur.

La syntaxe Mocha et Chai que nous connaissons déjà mais avec un environnement de travail simple et robuste ? YES, PLEASE!

Modern Security with Symfony’s shiny new Security Component

Le composant Security de Symfony est réputé comme étant un des composants complexes du framework, et souvent redouté par les développeurs. Récemment, il a pourtant été presque entièrement refait en interne et c’est ce que Ryan Weaver nous a brillamment démontré lors de la keynote de fin de journée.

Cela faisait bientôt 10 ans que le composant Security n’avait pas connu de changement majeur. Initialement sorti avec Symfony 2.0 RC1, ce composant était inspiré de Java Spring.

Nous, comme beaucoup d’autres développeurs, le trouvions très complet et puissant, mais souvent complexe, avec une courbe d’apprentissage très raide.

Il y a quelques temps, Guard est arrivé pour simplifier tout ça. En apparence seulement, car les mécanismes derrière Guard sont toujours les mêmes qu’à l’origine. Cela rendait la sécurité dans Symfony plus simple, mais dès que l’on souhaitait implémenter un moyen de connexion personnalisé, la complexité réapparaissait.

Oubliez tout cela, Security fait peau neuve dans Symfony 5.2 grâce à Wouter J (en tant que fonctionnalité expérimentale) !

  • Fini le mode anonyme que personne ne comprenait vraiment bien ;
  • Bienvenue à AuthenticatorInterface::authentificate(Request $request): PassportInterface qui remplace les 3 méthodes getCredentials(), checkCredentials() et getUser() ;
  • Le concept de Passport représente l’utilisateur qui souhaite s’authentifier, comme dans la vraie vie ;
  • Le concept de Badges permet maintenant d’ajouter des métadonnées au Passport (PasswordCredentials, token CSRF, RememberMe, PasswordRehash, …) ;
  • Le traitement des Badges, est effectué par les Listeners présents dans Symfony. Le framework s’assure d’ailleurs que tous les badges soient traités, et lancera une exception si un des Badges n’a pas été traité ;
  • 4 Events principaux permettent de « suivre » le processus d’authentification : CheckPassportEvent, AuthenticatedTokenCreatedEvent, LoginSuccessEvent et LoginFailureEvent. Ces Events rendent plus simple l’intégration d’une authentification 2FA ;
  • PUBLIC_ACCESS remplace IS_AUTHENTICATED_ANONYMOUSLY, fini l’ambiguïté ;
  • Le nouveau LogoutEvent permet d’agir au moment du logout, et par exemple, de modifier la Response ;
  • Et enfin, un système de connexion par « magic link » est désormais disponible nativement. Il existe aussi une intégration avec le nouveau composant RateLimiter pour limiter le nombre de tentatives de connexion.

New Security Schema

Cette réécriture n’est pas totalement terminée, d’où son statut expérimental. Nous sommes motivés pour la tester et contribuer à la rendre plus robuste afin qu’elle devienne la norme pour la sortie de Symfony 5.3 en Mai 2021 !

En résumé, la sécurité dans Symfony est devenue vraiment plus simple, et nous avons hâte de pouvoir essayer tout ça sur nos projets actuels, car la cerise sur le gâteau est que la migration est quasiment transparente pour la plupart des cas ! Une dizaine de lignes de configuration permet de bénéficier de ces nouveautés ! 🤩

Fin de journée

La fin d’une première journée de conférence rime en général avec soirée communautaire, ce n’est que partie remise. Rendez-vous demain pour notre compte rendu du second jour !

Nos formations sur le sujet

  • Logo Symfony

    Symfony

    Formez-vous à Symfony, l’un des frameworks web PHP les plus connus au monde

  • Logo Symfony avancée

    Symfony avancée

    Décou­vrez les fonc­tion­na­li­tés et concepts avan­cés de Symfo­ny

blog comments powered by Disqus