Nous étions à l’AFUP Day 2021 Online Rennes / Lille

Nous étions à l'AFUP Day 2021 Online Rennes / Lille

Situation sanitaire oblige, nous avons assisté une fois de plus à une conférence en ligne. Mais l’AFUP avait prévu pas mal de petites choses pour rendre ce mode « à distance » plus convivial ! Retour sur une journée de conférences en ligne pas tout à fait comme les autres !

Réconcilier le Back et le Front dans un projet Symfony par Quentin Machard

Quentin nous a rappelé, ou fait découvrir, le modèle de gestion atomique des éléments d’interface pour le développement frontend.

Les éléments unitaires (comme un bouton ou une image) sont représentés par des Atoms Ces éléments peuvent être assemblés pour former des Molecules (une « card » contenant une image, un texte et un bouton par exemple). Enfin, il est possible de combiner des Molecules entre elles pour obtenir des Organisms (on peut construire un carousel en assemblant plusieurs cards).

Mais comment faire fonctionner ce modèle pour les développeurs backend et frontend ? Dans le monde JS, Storybook permet de centraliser tous les composants d’interface, et Quentin est parti de ce principe pour créer Atomic Design Bundle. Ce bundle permet de créer tous les éléments présentés (Atoms, Molecules, Organisms) avec Twig, de les alimenter avec de vraies données provenant de la base. Il est possible d’ajouter la documentation technique d’utilisation de chaque élément. De cette manière, les développeurs backend et frontend partagent un lot d’éléments d’interface et chacun est capable de les utiliser simplement, que ce soit pendant la phase d’intégration ou de développement backend.

Chez JoliCode, nous utilisons une façon de faire similaire depuis quelque temps, sous l’impulsion de nos intégrateurs, nous allons donc certainement creuser encore plus ce sujet pour parvenir à fluidifier la collaboration entre front et back !

Slides

Retour d’expérience : CQRS à la rescousse de PrestaShop pour migrer vers Symfony par Mathieu Ferment

PrestaShop repose depuis ses débuts sur un framework MVC maison qui commençait à vieillir et surtout à accumuler du retard sur la concurrence en termes de fonctionnalités et de DX. C’est pourquoi l’équipe de PrestaShop a décidé de migrer du framework maison vers Symfony.

Cette migration a dû se faire en 2 étapes, puisque qu’un CMS eCommerce n’est pas une application classique du fait qu’un écosystème existe autour de lui. Un ensemble de modules et de thèmes sont développés par des contributeurs externes, et leur code repose sur une API exposée par PrestaShop.

Comment migrer à la fois la partie frontend et les controllers internes du CMS et la couche de services exposées aux modules, tout en rendant cela le moins contraignant possible pour les contributeurs ?

L’architecture CQRS paraît toute indiquée ici pour plusieurs raisons :

Une fois la couche de services encapsulée dans des Commands et Queries, l’équipe de PrestaShop est libre de changer l’implémentation des services, sans casser les Commands et Queries maintenant exposées pour les contributeurs externes. La partie frontend + controllers internes du CMS peut elle aussi bénéficier de cette nouvelle couche d’abstraction.

Pour la mise en place des 2 bus permettant de dispatcher les Commands et les Queries, le choix s’est porté sur le package league/tactician. La partie fastidieuse de création des Commands et Queries a été source de questionnement, tant la quantité de nouveaux fichiers créés était importante, mais finalement, c’est une conséquence normale de la mise en place d’une telle architecture. À chaque besoin de lecture/écriture correspondent plusieurs fichiers (Command ou Query + handler).

Une petite entorse a été faite aux règles de CQRS, celle de conserver les id auto-incrémentés au lieu de passer sur des UUIDs. Tout le code historique du CMS se base sur ces id, les remplacer aurait donc été un travail trop important avec peu de bénéfices au final.

Pour le debug de cette architecture, l’équipe a su tirer profit de Symfony et a donc créé un panel dédié pour visualiser les Handlers exécutés sur une page, depuis le Profiler de Symfony.

Finalement, il ne faut pas perdre de vue que CQRS est une architecture, que c’est donc déterminent à long terme, et que ça doit être vu comme un investissement. Il faut accepter que ça ne convient pas à toutes les situations.

Lock & Semaphore par Grégoire Pineau

Les race conditions (ou situation de compétition en français) sont des cas que l’on rencontre assez souvent sur des applications à fort trafic. En effet, comment gérer le cas où deux utilisateurs ajoutent au panier le même produit pour lequel il ne reste qu’une unité de stock ?

C’est pour résoudre ce type de cas que les composants Lock et Semaphore de Symfony ont été créés par Jérémy Derussé et Grégoire Pineau.

Mettre en place un Lock sur une ressource, identifiée par une Key, revient à la verrouiller pour l’utilisateur actuel (dans un contexte de requête HTTP, mais il en est de même si l’on parle de processus pour une application CLI).

$lock = $factory->createLock('add-product-to-cart-' . $product->getId());

if (!$lock->acquire()) {
    return;
}
try {
    // add the product to the cart
} finally {
    $lock->release();
}

Un Semaphore est un Lock partagé entre N processus, ce qui nous permet d’autoriser la lecture/écriture d’une ressource pour N processus dont on est certain qu’ils ne vont pas générer de race condition sur la ressource.

Les Semaphores sont stockés dans un store configurable, cependant seul Redis est disponible pour le moment. Pour les Locks, le stockage est possible dans Redis, PostgreSQL, Memcached, filesystem, Zookeeper, …

Slides

Le monde merveilleux des conteneurs d’injection de dépendances par Lior Chamla

Lior nous a fait une présentation très accessible du DIC, en expliquant pourquoi ce design pattern existe, quels sont les problèmes qu’il doit résoudre, et quelles sont ses limites et ses avantages.

À travers l’exemple d’un développeur junior qui aurait d’abord le réflexe de faire une « super méthode », il a su nous expliquer le principe de responsabilité unique ainsi que celui de l’injection de dépendances, afin d’introduire le conteneur d’injection de dépendances.

La vulgarisation de tous ces concepts techniques était très claire et efficace pour un développeur junior. Nous recommandons la conférence pour toute personne désireuse d’en apprendre plus sur le sujet !

Lazy Collections par Pol Dellaiera

Les collections permettent d’éviter toutes les incohérences liées aux fonctions natives de PHP relatives aux arrays.

Ce talk avait pour objectif de nous présenter une librairie proposant une implémentation des lazy collections en PHP. L’intérêt d’une telle librairie n’est pas forcément évident puisque PHP propose déjà plusieurs structures itérables ainsi que de très nombreuses fonctions natives pour réaliser des opérations sur des tableaux.

Pol Dellaiera nous explique que ces fonctions comportent toutefois des défauts qui peuvent rendre leur utilisation fastidieuse. Les callbacks manquent par exemple de consistance et l’ordre des arguments n’est pas toujours le même. De plus, elles ne fonctionnent qu’avec les array.

Les collections entendent régler ces problèmes, et on peut déjà en trouver dans Doctrine, Laravel, ou CakePHP par exemple. Elles permettent également une bonne lisibilité, en effectuant une opération par ligne : on applique d’abord un filtre, puis une map, puis un shuffle, tout cela en chaînant des méthodes. Cependant, la plupart ne sont que des wrappers de fonctions natives de PHP et ne fonctionnent qu’avec des array. La librairie de Pol Dellaiera permet de gérer tous les types d’iterable et de proposer plus de fonctionnalités que n’offrent les fonctions natives.

L’idée est d’itérer sur les éléments d’une collection un par un et de les retourner sans effectuer d’évaluation globale. Cela permet d’éviter des problèmes que l’on peut rencontrer avec des fonctions natives, comme par exemple l’écrasement d’une paire clé/valeur lors d’un array_flip si le tableau envoyé comprend 2 clés avec la même valeur. Pour ce faire, la libraire de Pol Dellaiera utilise les générateurs. Le lazy array_flip() se contente par exemple de yield des paires clé/valeur inversées, sans faire de vérification globale sur le résultat. Elle permet également d’opérer sur tout type d’iterable, plutôt que seulement sur les array.

Cette libraire apporte des réflexions intéressantes sur les faiblesses des fonctions natives de PHP. Nous ne savons pas encore si nous serions prêts à l’utiliser dans un de nos projets, mais elle propose en tout cas plusieurs pistes d’améliorations de certaines fonctions natives de PHP qui méritent d’être discutées, et pourquoi pas de faire l’objet d’une RFC ?

On se voit au Forum PHP ?

Cette journée de conférences s’est clôturée par un quiz assez corsé à propos des origines de PHP et de l’AFUP, avec à la clé un éléphpant dédicacé par Vincent Pontier, le créateur des éléphpants !

L’AFUP Day 2021 n’est pas fini pour autant, une seconde journée nous attend le 11 juin avec les villes de Toulouse et Tours.

Merci aux équipes bénévoles de l’AFUP, des antennes de Hauts-de-France et de Rennes pour l’organisation impeccable de cette journée ! Nous espérons tous vous voir au Forum PHP cet automne !

blog comments powered by Disqus