Détecteur de Changements Cassants dans l'API
Tu fais une vérification croisée du contrat réel d'une Web API C# (contrôleurs, DTOs, définitions de routes) par rapport à ses consommateurs TypeScript/JavaScript pour détecter une dérive de contrat — dans les deux sens — avant qu'elle ne se retrouve en production.
Quand l'utiliser
Déclenche l'utilisation quand l'utilisateur demande de :
- Vérifier si un changement de DTO/contrôleur va casser les applications frontend ou client
- Confirmer que le contrat client et API backend sont toujours synchronisés
- Auditer un endpoint spécifique, ou toute la surface d'API, pour les changements cassants avant une release
Ne l'utilise pas pour :
- Générer du code API à partir d'une spec OpenAPI (voir
openapi-to-application-code) - Mettre en place de nouveaux endpoints avec des docs OpenAPI (voir
aspnet-minimal-api-openapi) - Comparer directement deux fichiers de spec OpenAPI — cette compétence lit le code source, non les specs exportées
Processus
-
Découvrir les Stratégies JSON Globales et de Nommage :
- Vérifier
Program.csouStartup.cspour les options JSON actives (p. ex.JsonNamingPolicy.CamelCase,PropertyNamingPolicy, ou NewtonsoftCamelCasePropertyNamesContractResolver). - Par défaut, utiliser
camelCasepour le mappage des champs TypeScript/JavaScript si le camelCase global est configuré, sauf si remplacé par un attribut[JsonPropertyName("...")]explicite sur la propriété C#. - Ignorer les propriétés C# annotées avec
[JsonIgnore].
- Vérifier
-
Identifier la surface de contrat C#. Pour chaque action de Contrôleur dans le scope :
- Route : Base
[Route("...")]+ action[HttpGet("...")]/[HttpPost("...")]. Normaliser les paramètres de route (p. ex.{id:int}ou{id:guid}$\rightarrow${id}). - Request DTO : Extraire les noms de propriétés, types et règles de requirement :
- Requis si : annoté avec
[Required],[BindRequired], possède le modificateur C# 11required(public required string X), ou est un type de valeur non-nullable (int,Guid,bool) sans valeur par défaut. - Optionnel si : nullable (
string?,int?), ou a un initialiseur par défaut.
- Requis si : annoté avec
- Response DTO : Noms de propriétés, types et nullabilité.
- Codes de Statut Explicites : Attributs
[ProducesResponseType(statusCode)]et chemins de retour explicitesStatusCode(...).
- Route : Base
-
Trouver le consommateur TypeScript/JavaScript correspondant (avec Correspondance d'URL Normalisée) :
- Correspondance de client auto-généré (haute confiance) : chercher des fichiers client générés (sortie NSwag/OpenAPI Generator) et faire correspondre directement par le nom de méthode/interface généré.
- Correspondance de service/client écrit à la main (confiance moyenne) :
- Rechercher dans les fichiers TypeScript/JavaScript les appels de client HTTP (
fetch,axios, AngularHttpClient,ky, etc.) dont le motif d'URL normalisé correspond à la route du contrôleur. - Normaliser les template strings et concaténations (p. ex.,
${this.apiUrl}/users/${id}oubaseUrl + '/users/' + userId$\rightarrow$/users/{id}). - Faire correspondre les routes normalisées par rapport aux routes C# indépendamment du nommage des variables en TypeScript/JS.
- Rechercher dans les fichiers TypeScript/JavaScript les appels de client HTTP (
- Aucune correspondance trouvée : signaler comme « aucun consommateur client localisé » plutôt que de deviner — ne pas supposer qu'un endpoint est inutilisé simplement parce qu'une correspondance n'a pas été trouvée statiquement.
- Étiqueter chaque découverte avec laquelle de ces trois méthodes a été utilisée pour la localiser.
-
Comparer backend → frontend/client (casse le client) :
- Une propriété DTO renommée ou supprimée que l'interface TypeScript/JS ou le modèle d'objet attend toujours
- Un nouveau champ de requête obligatoire que le client n'envoie jamais
- Un code de statut de réponse que le client ne gère pas (p. ex. le contrôleur retourne maintenant 409 Conflict, mais le gestionnaire d'erreur client ne gère que 400/500)
- Le type d'un champ de réponse a changé (p. ex.
long$\rightarrow$string, ou non-nullable $\rightarrow$ nullable) d'une manière que le type client suppose différemment
-
Comparer frontend/client → backend (code client obsolète/mort vs. bugs silencieux) :
- Champ mort inoffensif : Client envoie une propriété de payload que le backend ignore sans erreur.
- Bug silencieusement cassé (Sévérité Haute) : La logique client lit une propriété de réponse que le backend ne retourne plus (entraînant
undefinedau runtime et des défaillances potentielles d'application).
-
Produire le rapport (voir Format de Sortie). Cette compétence ne modifie pas le code.
Format de Sortie
- Scope Audité — Contrôleurs, DTOs et fichiers TypeScript/JavaScript audités, ainsi que les stratégies de nommage JSON détectées (p. ex.
camelCaseactivé viaProgram.cs). - Backend → Casses Client — Regroupés par endpoint : ce qui a changé, méthode de correspondance utilisée (Auto-généré / Correspondance de Route Normalisée), impact exact sur le client, et sévérité (Erreur de Compilation vs. Défaillance Silencieuse au Runtime).
- Dérive Client → Backend — Champs obsolètes envoyés ou attendus, en distinguant explicitement les champs morts inoffensifs des logiques d'UI client silencieusement cassées.
- Aucun Consommateur Trouvé — DTOs/endpoints non appariés nécessitant une confirmation manuelle.
- Résumé de Confiance de Correspondance — Répartition des découvertes provenant de clients auto-générés vs. routes écrites à la main normalisées vs. routes non appariées.
Lignes Directrices
- Normalisation d'URL : Toujours supprimer les paramètres de requête (
?status=active) et normaliser les paramètres de chemin (${id}/:id/{id}) avant de comparer les routes. - Stratégies de Nommage : Ne jamais supposer qu'un nom de propriété C# correspond verbatim à une propriété TypeScript/JS sans vérifier
[JsonPropertyName("...")]ou les paramètres deJsonNamingPolicy.CamelCaseglobaux. - Nuances C# Modernes : Vérifier le mot-clé C# 11
requiredet les annotations#nullable enable(string?vsstring) lors de l'évaluation des propriétés obligatoires. - Agnostique du Framework : Appliquer la correspondance de contrat sur tout client TypeScript ou JavaScript (Fetch, Axios, Angular, React, Vue, Svelte, Node.js).
- Ne Jamais Inventer : Si aucun service client ou DTO correspondant n'est trouvé, signaler « Aucun consommateur localisé via recherche statique » — ne jamais deviner un appairage basé uniquement sur des noms de classe vagues.
- Rapport Uniquement : Ne pas modifier le code ; produire un rapport d'audit lisible et actif.