Balinea - Une mise en prod en beauté - 3/3

Évolutions logicielles. Quand il faut faire des choix techniques.

Pour clôturer cette étude de cas, j’aborderai brièvement les principales évolutions logicielles qui ont eu lieu depuis un an sur le code des applications Balinea.

Monolith or not monolith?

Ces applications (on y compte pas moins de 10 “AppKernels” Symfony aujourd’hui, qui sont autant de points d’entrées vers des apps Web différentes) sont situées sur un unique dépôt git.

Avec le temps, les évolutions et les nouvelles applications que nous avons ajoutées petit à petit (nous avons le middle-office originel, un espace d’administration, le site public, une application dédiée aux assets, deux APIs…), ont fini par constituer aujourd’hui un bien imposant monolithe, contenant une centaine de milliers de lignes de code PHP et JavaScript.

Cela va certes plutôt à l’encontre des tendances du moment qui poussent à la mise en place d’architectures “micro services”. Cependant, à l’heure de la rétrospective, et après presque un an et demi passé sur le code dont six mois aujourd’hui en production (du code “de la vraie vie”, donc, poussé régulièrement en ligne sur un site marchand générant un important chiffre d’affaire quotidien), nous n’avons jusqu’ici pas eu de raison de regretter ce choix du monolithe.

Cela simplifie grandement les développements dès lors qu’ils touchent à des parties partagées entre plusieurs applications (le Modèle notamment), ainsi que le déploiement, la synchronisation des membres de l’équipe lorsqu’ils travaillent sur des aspects parallèles d’un même chantier, etc.

Le point d’entrée des applications (les fameux fichiers “app.php” et “app_dev.php” de Symfony) est certes unique, mais comporte un routage (simpliste mais fonctionnel) du kernel à démarrer en fonction du nom de domaine. A partir du moment où un AppKernel est lancé, il ne charge que les Bundles et les ressources dont il a besoin, et le code de chaque application est suffisamment indépendant pour que le monolithe ne soit pas pour autant un énorme plat de spaghettis.

Entre le RAD et le DDD, il doit y avoir un juste milieu

La première application sur laquelle nous avons travaillé dans le cadre de cette refonte a été le middle-office, qui est une application présentant pour l’essentiel des formulaires dont les champs correspondent exactement à ceux de la base de données : des “CRUD” (Create, Read, Update, Delete). Etant donnés les délais qu’étaient les nôtres, et la facilité des développeurs à travailler avec ce type de patterns auxquels il étaient habitués, nous ne nous sommes guère posé de question et avons continué à faire correspondre nos formulaires Symfony à nos Entités Doctrine (et donc aux tables de notre base de données).

Au fur et à mesure des évolutions cependant, nous nous sommes trouvés de plus en plus souvent avec des demandes fonctionnelles qui nous obligeaient à casser ce simple paradigme. Nous avons alors adapté nos formulaires Symfony, et avons commencé à casser des correspondances “form <-> entity” sur tel et tel champ, avec l’option “mapped = false” des FormTypes de Symfony. Ces champs “non mappés” se trouvaient donc non traités, et nous devions gérer manuellement l’attribution de leurs données sur nos entités dans nos classes de “FormHandlers” (voire directement dans les Contrôleurs).

Cela fonctionne, certes, mais ça devient vite un réel bazar, avec du code sur lequel il est devenu vraiment désagréable de travailler et sur lequel la maintenance n’est pas aisée.

C’est suite aux conseils de Jérémy de KNPLabs, lors de sa brillante intervention sur le projet Balinea, que nous avons commencé à explorer un aspect bien connu des pratiquants du “DDD”, le Domain Driven Development. En DDD le besoin métier structure très fortement le code. Les entités ne sont pas “CRUD”, et ne peuvent être créées et mises à jour que via des actions métier (“créer une facture”, “rembourser un paiement”, “appliquer une promotion”, plutôt que l’appel de plusieurs setters bas niveau sur des entités).

DDD Day 2016 Ne laissez pas les formulaires Symfony influencer votre modèle par Jeremy Barthe YouTube

Nous ne présenterons pas ici les détails du DDD, mais si cela vous intéresse autant que nous vous trouverez toute la littérature nécessaire sur le vaste Web, par exemple sur ces slides du dit Jérémy et sur cet article de Bernhard Schussek, principal auteur des formulaires de Symfony.

Toujours dans la mouvance du DDD, nous avons également intégré progressivement le pattern “Message Bus”, avec l’implémentation de Matthias Noback. Après un petit temps de rôdage, où nous ne l’avons pas forcément utilisé à bon escient (i.e. dans des contextes parfois très applicatifs, et pas spécialement “métiers”), grâce à lui nous avons commencé à obtenir un meilleur découplage de nos composants. Cela a facilité nos tests unitaires, et nous avons obtenu un code plus proche du besoin fonctionnel, avec lequel il est plus agréable de travailler.

Si vous n’avez pas encore essayé ces CommandBus et EventBus, nous ne pouvons que vivement vous le recommander ! Le meilleur point de départ est sûrement la série d’articles d’introduction de leur auteur, dont le premier se situe ici.

Nous n’avons pas pratiqué le Domain Driven Development en soi chez Balinea, mais en saupoudrant notre application de certains de ses principes nous avons clairement rendu son code PHP plus élégant et plus évolutif.

Conclusion

Deux ans après le début de notre activité de consulting et de développement pour Balinea, notre collaboration avec la start-up s’est terminée avec la satisfaction d’avoir contribué tous ensemble avec l’équipe à apporter plus de qualité et de stabilité au code et au processus de développement. La version Symfony du site est en ligne depuis le mois de novembre 2015 mais cette mise en production n’est que le début d’une grande aventure, de très nombreuses évolutions restant au programme.

Nous espérons avoir contribué à notre échelle à la réussite de la société, chez laquelle nous nous sommes pleinement impliqués et avec qui ce fut un grand plaisir de travailler :).

About the author :
It’s not a buzzword but reality when we say that Olivier is a real fullstack developer. Not only a senior Symfony developer, he was also a former lead dev on Flash and then tried all kinds of JS libraries.

You will be safe with Olivier if you need a soft skilled consultant who helps your CTO to make the right architecture, techno and methodology choices! He has a long experience as a freelancer in Paris, and knows how to handle code legacy ;)

Here are some of his multiple skills : Browserify, Node.js, Docker, Silex, Ruby on Rails, Coffeescript, ES, gulp…