» Le changement est la seule constante… » – Héraclite (philosophe)
Les outils, bibliothèques et frameworks que nous utilisons aujourd’hui pour créer nos applications Web sont radicalement différents de ceux que nous utilisions il y a quelques années à peine.
Dans quelques années, la plupart de ces technologies auront à nouveau radicalement changé. Pourtant, beaucoup d’entre nous en font une partie centrale et inextricable de nos applications.
Nous importons, utilisons et héritons des frameworks de saveur du mois comme s’ils allaient tous être présents et inchangés pour toujours. Eh bien they ils ne le sont pas. Et c’est un problème.
Après plus de 20 ans de développement, de conception et d’architecture d’applications Web, j’en suis venu à apprécier deux vérités importantes:
- Les dépendances externes constituent une grande menace pour la stabilité et la viabilité à long terme de toute application.
- Il est de plus en plus difficile, voire impossible, de créer n’importe quel type d’application non triviale sans tirer parti des dépendances externes.
Cet article vise à concilier ces deux vérités afin que nos applications aient les meilleures chances de survie à long terme.
- Le trou du lapin est en effet très profond.
- 1. Dépendances que nous contrôlons
- 2. Dépendances que nous ne contrôlons pas
- 3. Dépendances une fois supprimées
- Pourquoi les dépendances de code tiers sont bonnes
- Pourquoi les dépendances de code tiers sont mauvaises
- Équilibrer le bien et le mal
- Aidez-moi à aider les autres
Le trou du lapin est en effet très profond.
Si nous commençons à penser à toutes les choses dont dépendent nos applications Web, il est facile de penser à une douzaine ou plus avant même d’arriver au code:
- Alimentation
- Connectivité
- Pare-feu
- DNS
- Matériel serveur (CPU, Disque, Ram, Ram)
- Refroidissement
- Plateforme de virtualisation
- Plateforme conteneur
- Système d’exploitation
- Plate-forme de serveur Web
- Plate-forme de serveur d’applications
- Navigateur Web
En tant que développeurs, il est bon d’être au courant de ces choses, mais nous ne pouvons souvent pas faire grand-chose à leur sujet. Alors, ignorons-les pour l’instant et ne parlons que du code.
Dans le code, il existe trois types de dépendances:
1. Dépendances que nous contrôlons
Il s’agit d’un code écrit et appartenant à nous ou à notre organisation.
2. Dépendances que nous ne contrôlons pas
Il s’agit d’un code écrit par un fournisseur tiers ou une communauté de logiciels open source.
3. Dépendances une fois supprimées
Ce sont les dépendances de code dont dépendent nos dépendances de code tierces. (Dis ça trois fois vite!)
Nous allons parler principalement des dépendances que nous ne contrôlons pas.
Les dépendances que nous contrôlons et les dépendances une fois supprimées peuvent toujours causer des maux de tête, mais dans le cas des dépendances que nous contrôlons, nous devrions pouvoir intervenir directement et atténuer tout problème.
Dans le cas des dépendances une fois supprimées, nous pouvons généralement compter sur un tiers pour nous en occuper, car ils en dépendent également.
Pourquoi les dépendances de code tiers sont bonnes
Une grande partie de votre application web existe pour résoudre les problèmes courants: authentification, autorisation, accès aux données, gestion des erreurs, navigation, journalisation, cryptage, affichage d’une liste d’éléments, validation des entrées de formulaire, etc…
Quelle que soit la pile technologique que vous utilisez, il y a de fortes chances que des solutions communes à ces problèmes existent et soient disponibles sous forme de bibliothèques que vous pouvez facilement acquérir et brancher sur votre base de code. Écrire n’importe lequel de ces trucs complètement à partir de zéro est généralement une perte de temps.
Vous souhaitez vous concentrer sur un code qui résout un problème peu commun ou résout un problème commun d’une manière peu commune. C’est ce qui rend votre application précieuse : le code qui implémente les règles métier uniques à votre application seule — la » sauce secrète « . »
Algorithme de recherche et de classement des pages de Google, filtrage de la chronologie de Facebook, section « recommandé pour vous » de Netflix et algorithmes de compression de données — le code derrière toutes ces fonctionnalités est « sauce secrète. »
Le code tiers — sous forme de bibliothèques — vous permet d’implémenter rapidement ces fonctionnalités banalisées de votre application, afin que vous puissiez rester concentré sur votre sauce secrète. »
Pourquoi les dépendances de code tiers sont mauvaises
Jetez un œil à toute application Web non triviale construite au cours des deux dernières années et vous serez absolument étonné par la quantité de code provenant d’une bibliothèque tierce. Que se passe-t-il si une ou plusieurs de ces bibliothèques tierces changent radicalement, disparaissent ou se cassent?
Si c’est open-source, vous pouvez peut-être le réparer vous-même. Mais dans quelle mesure comprenez-vous tout le code de cette bibliothèque que vous ne possédez pas? Une grande raison pour laquelle vous utilisez une bibliothèque en premier lieu est d’obtenir les avantages du code sans avoir à vous soucier de tous les détails. Mais maintenant tu es coincé. Vous avez complètement lié votre fortune à ces dépendances que vous ne possédez pas et que vous ne contrôlez pas.
Peut-être pensez-vous que j’exagère, ou que je parle d’un point de vue purement académique. Permettez—moi de vous assurer que j’ai des dizaines d’exemples de clients qui se sont complètement snookés en intégrant trop étroitement du code tiers dans leur application. Voici un exemple récent:
Un de mes anciens clients a construit leur application à l’aide d’un fournisseur de services Backend-as-a-Service appartenant à Facebook, appelé Parse. Ils ont utilisé une bibliothèque client JavaScript fournie par Parse pour consommer le service d’analyse. Dans le processus, ils ont étroitement couplé tout leur code — y compris le code « sauce secrète » — à cette bibliothèque.
Trois mois après le lancement initial du produit de mon client — au moment où il commençait à avoir une bonne traction avec de vrais clients payants —, Parse a annoncé sa fermeture.
Maintenant, au lieu de se concentrer sur l’itération de leur produit et de développer leur base de clients, mon client a dû trouver comment migrer vers une version open source auto-hébergée de Parse ou remplacer complètement Parse.
La perturbation que cela a causée pour une application jeune et naissante était si énorme que mon client a finalement abandonné l’application entièrement.
Équilibrer le bien et le mal
Il y a plusieurs années, ma solution de choix pour surmonter les risques tout en conservant les avantages des bibliothèques tierces était de les envelopper à l’aide du modèle d’adaptateur.
Essentiellement, vous enveloppez le code tiers dans une classe ou un module d’adaptateur que vous avez écrit. Cela fonctionne ensuite pour exposer les fonctions des bibliothèques tierces d’une manière que vous contrôlez.
En utilisant ce modèle, si une bibliothèque ou un framework tiers change ou disparaît, il vous suffit de corriger un peu de code d’adaptateur. Le reste de votre application reste intact.
Cela sonne bien sur le papier. Lorsque vous avez des dépendances autonomes qui ne fournissent que quelques fonctions, cela fera l’affaire. Mais les choses peuvent vite devenir laides.
Pouvez-vous imaginer devoir envelopper toute la bibliothèque React (y compris JSX) avant de l’utiliser? Que diriez-vous d’envelopper jQuery, ou Angular, ou le framework Spring en Java? Cela devient rapidement un cauchemar.
De nos jours, je recommande une approche plus nuancée
Pour chaque dépendance que vous souhaitez ajouter à votre base de code, évaluez le niveau de risque qu’elle introduira en multipliant deux facteurs:
- La probabilité que la dépendance change de manière matérielle.
- Le montant des dommages qu’une modification importante de la dépendance causerait à votre application.
Une bibliothèque ou un framework tiers est moins susceptible de changer lorsque certaines ou toutes les choses suivantes sont vraies:
- Il existe depuis plusieurs années et a eu plusieurs versions majeures.
- Il est largement utilisé par de nombreuses applications commerciales.
- Il bénéficie du soutien actif d’une grande organisation — de préférence une entreprise ou une institution de renom.
Une bibliothèque ou un framework tiers causera moins de dommages à votre application lorsque certaines ou toutes les choses suivantes sont vraies:
- Il n’est utilisé que par une petite partie de votre application, plutôt que d’être utilisé partout.
- Le code qui en dépend ne fait pas partie de cette « sauce secrète » dont j’ai parlé plus tôt.
- Sa suppression nécessite des modifications minimales de votre base de code.
- Votre application entière est très petite et peut être réécrite rapidement. (Soyez prudent avec celui—ci – c’est rarement vrai très longtemps.)
Plus quelque chose est risqué, plus vous devriez avoir de chances de l’envelopper ou de l’éviter complètement.
En ce qui concerne le code qui est vraiment au cœur de la proposition de valeur de votre application — votre « sauce secrète » — vous devez en être extrêmement protecteur. Rendez ce code aussi indépendant que possible. Si vous devez absolument utiliser une dépendance, envisagez de l’injecter plutôt que de la référencer directement. Même alors, soyez prudent.
Parfois, cela signifie dire « non » à une bibliothèque tierce que vous pensez vraiment cool, ou que vous voulez vraiment utiliser pour une raison ou une autre. Sois fort. Croyez-moi, ça va payer. Il suffit de demander à toutes ces personnes qui ont beaucoup investi dans la toute première version d’Angular, ou à mon ancien client qui a utilisé Parse partout. C’est pas marrant. Crois-moi.
En parlant de plaisir, jetez un oeil à ceci…
L’image ci-dessus est le graphique de dépendance pour une application appelée TinyTag Explorer.
Générer un graphique de dépendances pour vos applications existantes est un excellent moyen de comprendre le niveau de risque introduit par vos dépendances. J’ai dressé une liste d’outils gratuits pour générer des graphiques similaires à ceux ci-dessus dans une variété de langages, y compris JavaScript, C #, Java, PHP et Python. Vous pouvez l’obtenir ici.
Aidez-moi à aider les autres
Je veux aider autant de développeurs que possible en partageant mes connaissances et mon expérience avec eux. Aidez-moi en cliquant sur le bouton ❤ recommander (coeur vert) ci-dessous.
Enfin, n’oubliez pas de récupérer votre liste de générateurs de graphes de dépendances gratuits ici.