Aikido

Comment éviter de rompre les contrats d'API publiques : maintien de 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. Lorsque les clients dépendent du format de requête, de la structure de réponse ou du comportement d'un point de terminaison, toute modification entraîne une rupture de leur code. Les ruptures 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

Perturbation des clients et confiance : Les ruptures d'API provoquent des défaillances immédiates dans les applications client de production. Les utilisateurs sont confrontés à des erreurs, à des pertes de données ou à des interruptions de service complètes. Cela nuit à la confiance entre les fournisseurs d'API et les consommateurs, et viole le contrat implicite selon lequel les API stables restent stables.

Coûts de coordination : La coordination des changements de rupture entre plusieurs équipes de clients est coûteuse et lente. Chaque équipe a besoin de temps pour mettre à jour le code, tester les changements et les déployer. Pour les API publiques dont les clients sont inconnus (applications mobiles, intégrations tierces), la coordination est impossible.

Prolifération des versions : Une mauvaise gestion des ruptures conduit à la maintenance simultanée de plusieurs versions de l'API. Chaque version nécessite des chemins de code, des tests, une documentation et des corrections de bogues distincts, ce qui multiplie la charge de maintenance de manière exponentielle.

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 ce n'est pas correct : Renommer name en fullName interrompt tous les clients existants qui attendent le champ name. Le code client accédant à response.name recevra un code non défini, ce qui provoquera des erreurs. Ce changement oblige 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 cela est-il important ? Garder l'ancien nom maintient la compatibilité ascendante tout en ajoutant Nom complet pour les nouveaux clients. Il est également possible de créer un nouveau point d'accès versionné (/api/v2/) permet d'effectuer des changements sans affecter les clients existants qui utilisent encore la fonction /api/v1/.

Conclusion

Faites évoluer les API par le biais de modifications additives : ajoutez de nouveaux champs, ajoutez de nouveaux points de terminaison, ajoutez des paramètres facultatifs. Lorsque des changements radicaux sont inévitables, utilisez le versionnage de l'API pour exécuter simultanément les anciennes et les nouvelles versions. Déclassez les anciens champs en indiquant clairement les délais et les guides de migration avant de les supprimer.

FAQ

Vous avez des questions ?

Quels sont les changements considérés comme des ruptures ?

La suppression de champs dans les réponses, le changement de nom des champs, la modification des types de champs (chaîne de caractères ou nombre), l'obligation d'utiliser des paramètres facultatifs, la modification des codes d'état HTTP pour les conditions existantes, la modification des exigences en matière d'authentification et la modification des formats de réponse en cas d'erreur. L'ajout de nouveaux paramètres de demande obligatoires ou la suppression complète de points de terminaison constituent également des changements radicaux.

Comment ajouter de nouveaux champs obligatoires sans perturber les clients ?

Rendre le nouveau champ facultatif au départ, avec une valeur par défaut raisonnable. 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 obligatoires des champs facultatifs existants sans version.

Quelle est la différence entre le versionnement et la dépréciation de l'API ?

Le versionnage 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 une éventuelle suppression. Utilisez le versionnement pour les changements majeurs, et la dépréciation pour les suppressions progressives de fonctionnalités mineures.

Pendant combien de temps dois-je conserver les versions d'API obsolètes ?

Pour les API publiques, conserver les versions obsolètes pendant au moins 12 à 18 mois. Pour les API internes, coordonnez-vous avec les équipes de clients pour établir un calendrier de migration. Prévenir toujours à l'avance (3 à 6 mois minimum) avant de supprimer les points de terminaison obsolètes. Surveiller les mesures d'utilisation pour s'assurer que les clients ont migré avant la fermeture.

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

Oui, l'ordre des champs de l'objet JSON ne fait pas partie du contrat de l'API. Les clients bien écrits analysent le JSON en fonction du nom du champ, et non de sa position. Toutefois, il convient d'effectuer des tests approfondis, car certains clients mal écrits peuvent dépendre de l'ordre des champs. Pour les tableaux, l'ordre est généralement important et ne doit pas être modifié, sauf si cela est documenté.

Comment puis-je modifier les API sans changer le chemin d'accès à l'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 du 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.

Obtenir la sécurité gratuitement

Sécurisez votre code, votre cloud et votre environnement d'exécution dans un système central.
Trouvez et corrigez rapidement et automatiquement les vulnérabilités.

Aucune carte de crédit n'est requise | Scanner les résultats en 32sec.