Les dépendances de code sont le diable.

«Le changement est la seule constante…» - Heraclitus (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 à peine quelques années.

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 la saveur du mois comme s'ils allaient tous être là et inchangés pour toujours. Eh bien… 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'ai appris à apprécier deux vérités importantes:

  1. Les dépendances externes constituent une grande menace pour la stabilité et la viabilité à long terme de toute application.
  2. Il est de plus en plus difficile - voire impossible - de créer tout 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 terrier du lapin est en effet très profond.

Si nous commençons à penser à tout ce dont dépendent nos applications Web, il est facile de penser à une douzaine ou plus avant même d'arriver au code:

  • Puissance
  • Connectivité
  • Pare-feu
  • DNS
  • Matériel serveur (CPU, disque, RAM,…)
  • Refroidissement
  • Plateforme de virtualisation
  • Plateforme de conteneurs
  • Système opérateur
  • Plateforme de serveur Web
  • Plateforme de serveur d'applications
  • Navigateur Web

En tant que développeurs, il est bon d'être conscient 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 tiers. (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 encore causer des maux de tête, mais dans le cas des dépendances que nous contrôlons, nous devrions être en mesure d'intervenir directement et d'atténuer les problèmes.

Dans le cas des dépendances une fois supprimées, nous pouvons généralement compter sur un tiers pour s'en occuper à notre place, 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, chiffrement, affichage d'une liste d'éléments, validation des entrées de formulaire, etc.

Quelle que soit la pile de technologies 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 vous connecter à votre base de code. Ecrire complètement tout cela à partir de zéro est généralement une perte de temps.

Vous voulez vous concentrer sur du code qui résout un problème inhabituel ou résout un problème courant de manière inhabituelle. C'est ce qui rend votre application précieuse: le code qui implémente les règles métier qui sont uniques à votre application uniquement - la «sauce secrète».

L'algorithme de recherche et de classement des pages de Google, le filtrage de la chronologie de Facebook, la section «Recommandé pour vous» de Netflix et les algorithmes de compression de données - le code derrière toutes ces fonctionnalités est «la sauce secrète».

Le code tiers, sous la forme de bibliothèques, vous permet de mettre en œuvre 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 à n'importe quelle application Web non triviale créée au cours des deux dernières années et vous serez absolument étonné par la quantité de code qui provient en fait d'une bibliothèque tierce. Que faire 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 des principales raisons pour lesquelles 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 vous êtes 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 - 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 juste un exemple récent…

Un de mes anciens clients a créé leur application à l'aide d'un fournisseur Backend-as-a-Service appartenant à Facebook, appelé Parse. Ils ont utilisé une bibliothèque cliente JavaScript fournie par Parse pour utiliser le service Parse. 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 même où ils commençaient à obtenir une bonne traction avec de vrais clients payants - Parse a annoncé sa fermeture.

Désormais, au lieu de se concentrer sur l'itération de leur produit et sur la croissance de leur clientèle, mon client devait 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é pour une jeune application naissante était si énorme que mon client a finalement mis au rebut 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 encapsulez le code tiers dans une classe d'adaptateur ou un module 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 une infrastructure tierce change ou disparaît, vous n'avez qu'à 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 moche.

Pouvez-vous imaginer avoir à encapsuler toute la bibliothèque React (y compris JSX) avant de l'utiliser? Que diriez-vous d'encapsuler jQuery, ou Angular, ou le framework Spring en Java? Cela devient rapidement un cauchemar.

Ces jours-ci, 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:

  1. La probabilité que la dépendance change de manière matérielle.
  2. Le montant des dommages qu'un changement important de la dépendance causerait à votre application.

Une bibliothèque ou un framework tiers est moins susceptible de changer lorsque certaines ou toutes les conditions 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 bien connue.

Une bibliothèque ou un framework tiers causera moins de dommages à votre application lorsque certaines ou toutes les conditions 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.
  • Le supprimer nécessite des modifications minimes 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 pendant très longtemps.)

Plus quelque chose est risqué, plus vous devriez avoir de chances de l'envelopper ou de l'éviter complètement.

Quand il s'agit du code qui est vraiment au cœur de la proposition de valeur de votre application - votre «sauce secrète» - vous devez être extrêmement protecteur à son égard. 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 jugez vraiment cool ou que vous voulez vraiment utiliser pour une raison ou une autre. Être fort. Croyez-moi, cela sera payant. Il suffit de demander à tous ceux qui ont beaucoup investi dans la toute première version d'Angular, ou à mon ancien client qui a utilisé Parse partout. Ce n'est pas amusant. Crois moi.

En parlant de plaisir, jetez un œil à ceci…

L'image ci-dessus est le graphique de dépendance d'une application appelée TinyTag Explorer.

La génération d'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 rassemblé une liste d'outils gratuits pour générer des graphiques similaires à ceux ci-dessus dans une variété de langages, notamment JavaScript, C #, Java, PHP et Python. Vous pouvez l'obtenir ici.

Aidez-moi à aider les autres

Je souhaite aider autant de développeurs que possible en partageant mes connaissances et mon expérience avec eux. Veuillez m'aider en cliquant sur le bouton ❤ recommander (cœur vert) ci-dessous.

Enfin, n'oubliez pas de récupérer votre liste de générateurs de graphes de dépendances gratuits ici.