Aikido

Comment éviter de rompre les contrats d'API publics : maintenir la compatibilité ascendante

Maintenabilité

Règle

Éviter d'interrompre publique API publiques.
Les changements pour publics API publics qui serait briser
existants clients clients sont de l'entreprise changements.
Pensez de l API comme comme a promesse - changeant
la après clients dépendent sur l'entreprise rompt leur code.

Langues supportées : PHP, Java, C#, Python, JavaScript, TypeScript

Introduction

Les API publiques sont des contrats entre votre service et ses consommateurs. Dès lors que les clients dépendent du format de requête, de la structure de réponse ou du comportement d'un endpoint, toute modification rompt leur code. Les changements majeurs (breaking changes) obligent tous les clients à se mettre à jour simultanément, ce qui est souvent impossible lorsque vous ne contrôlez pas les clients. Les applications mobiles ne peuvent pas être mises à jour de force, les intégrations tierces nécessitent un temps de migration, et les systèmes hérités peuvent ne jamais être mis à jour.

Pourquoi c'est important

Interruption client et confiance : Les changements d'API disruptifs entraînent des défaillances immédiates dans les applications clientes en production. Les utilisateurs subissent des erreurs, des pertes de données ou des pannes de service complètes. Cela nuit à la confiance entre les fournisseurs et les consommateurs d'API, et viole le contrat implicite selon lequel les API stables restent stables.

Coûts de coordination : Coordonner les breaking changes entre plusieurs équipes clientes est coûteux et lent. Chaque équipe a besoin de temps pour mettre à jour le code, tester les changements et déployer. Pour les API publiques avec des clients inconnus (applications mobiles, intégrations tierces), la coordination est impossible.

Prolifération des versions : Les changements majeurs mal gérés entraînent la maintenance simultanée de plusieurs versions d'API. Chaque version nécessite des chemins de code, des tests, une documentation et des corrections de bugs distincts, multipliant exponentiellement la charge de maintenance.

Exemples de code

❌ Non conforme :

// Version 1: Original API
app.get('/api/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({ id: user.id, name: user.name });
});

// Version 2: Breaking change - renamed field
app.get('/api/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({
        id: user.id,
        fullName: user.name  // Breaking: 'name' renamed to 'fullName'
    });
});

Pourquoi c'est incorrect : Renommer 'name' en 'fullName' rompt tous les clients existants qui s'attendent au champ 'name'. Le code client accédant à response.name recevra 'undefined', provoquant des erreurs. Ce changement force tous les clients à se mettre à jour simultanément ou à échouer.

✅ Conforme :

// Version 2: Additive change - keeps old field, adds new
app.get('/api/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({
        id: user.id,
        name: user.name,           // Keep for backward compatibility
        fullName: user.name        // Add new field (deprecated 'name')
    });
});

// Or use API versioning
app.get('/api/v2/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({ id: user.id, fullName: user.name });
});

Pourquoi c'est important : Garder l'ancien nom le champ maintient la compatibilité ascendante tout en ajoutant fullName pour les nouveaux clients. Alternativement, la création d'un nouveau endpoint versionné (/api/v2/) permet des modifications incompatibles sans affecter les clients existants qui utilisent encore /api/v1/.

Conclusion

Faire évoluer les API par des modifications additives : ajouter de nouveaux champs, de nouveaux endpoints, des paramètres optionnels. Lorsque des changements cassants (breaking changes) sont inévitables, utilisez le versioning d'API pour exécuter simultanément les anciennes et les nouvelles versions. Dépréciez les anciens champs avec des échéanciers clairs et des guides de migration avant de les supprimer.

FAQ

Des questions ?

Quels changements sont considérés comme cassants ?

La suppression de champs des réponses, le renommage de champs, la modification des types de champs (chaîne de caractères à nombre), le fait de rendre des paramètres optionnels obligatoires, la modification des codes de statut HTTP pour des conditions existantes, l'altération des exigences d'authentification et la modification des formats de réponse d'erreur. L'ajout de nouveaux paramètres de requête obligatoires ou la suppression complète de points d'accès (endpoints) sont également des changements majeurs.

Comment ajouter de nouveaux champs obligatoires sans impacter les clients ?

Rendez le nouveau champ facultatif initialement avec une valeur par défaut pertinente. Documentez le changement et donnez aux clients le temps de l'adopter. Après un délai suffisant (6 à 12 mois pour les API publiques), rendez le champ obligatoire dans une nouvelle version de l'API. Ne rendez jamais des champs facultatifs existants obligatoires sans versioning.

Quelle est la différence entre le versioning d'API et la dépréciation ?

Le versioning crée un nouveau point de terminaison (/v2/users) à côté de l'ancien, permettant aux deux de coexister. La dépréciation marque un ancien point de terminaison ou champ comme obsolète tout en le maintenant fonctionnel, avec un calendrier pour un retrait éventuel. Utilisez le versioning pour les changements majeurs, la dépréciation pour l'élimination progressive des fonctionnalités mineures.

Combien de temps dois-je maintenir les versions d'API dépréciées ?

Pour les API publiques, maintenez les versions dépréciées pendant au moins 12 à 18 mois. Pour les API internes, coordonnez-vous avec les équipes clientes pour établir un calendrier de migration. Fournissez toujours un préavis (3 à 6 mois minimum) avant de supprimer les endpoints dépréciés. Surveillez les métriques d'utilisation pour vous assurer que les clients ont migré avant l'arrêt.

Puis-je modifier l'ordre des champs de réponse ?

Oui, l'ordre des champs d'un objet JSON ne fait pas partie du contrat d'API. Les clients bien conçus parsifient le JSON par nom de champ, et non par position. Cependant, testez minutieusement car certains clients mal écrits pourraient dépendre de l'ordre des champs. Pour les tableaux, l'ordre est généralement important et ne devrait pas changer sauf si documenté.

Comment versionner les API sans modifier le chemin d'URL ?

Utilisez les en-têtes HTTP : Accept: application/vnd.myapi.v2+json ou des en-têtes personnalisés comme API-Version: 2. Les paramètres de requête fonctionnent également : /api/users?version=2. La négociation de contenu via les en-têtes est plus propre mais plus difficile à tester dans les navigateurs. Choisissez une stratégie et utilisez-la de manière cohérente.

Sécurisez-vous maintenant.

Sécuriser votre code, votre cloud et votre runtime dans un système centralisé unique.
Détectez et corrigez les vulnérabilités rapidement et automatiquement.

Pas de carte de crédit requise | Résultats du scan en 32 secondes.