FastAPI : détection des endpoints non documentés via OpenAPI

FastAPI : détection des endpoints non documentés via OpenAPI

Introduction

Dans un environnement où les APIs FastAPI sont déployées en continu, la divergence entre le schéma OpenAPI et les traces réelles peut entraîner des endpoints fantômes – des routes utilisées mais non documentées. Ces incohérences augmentent le MTTR, compliquent la conformité RGPD et faussent les métriques d’observabilité. Cet article propose un deep‑dive sur le concept central : la corrélation traces‑spec. Vous y trouverez une analogie claire, une description détaillée du processus, et un script prêt à l’emploi.


1. Le concept clé : corrélation traces‑spec

1.1 Pourquoi la corrélation est cruciale

Imaginez votre API comme un plan d’architecture (OpenAPI) et vos requêtes réelles comme les travaux sur le terrain (traces). Si le plan ne reflète pas les travaux, les ingénieurs ne peuvent pas valider la conformité ni anticiper les incidents. En observabilité, la corrélation consiste à mapper chaque trace à un chemin du schéma. Lorsque le mapping échoue, on identifie un endpoint non documenté.

1.2 Diagramme en mots

[Schéma OpenAPI] ──► Matcher ◄── [Traces d’exécution]
          ▲                     │
          │                     ▼
   Endpoints documentés   Endpoints non documentés

Le matcher compare les chemins (ex. /users/{id}) aux chemins observés (/users/42). Si aucune correspondance n’est trouvée, le chemin est signalé comme orphan.


2. Mise en place technique

2.1 Prérequis

  • Application FastAPI en production avec instrumentation OpenTelemetry ou tout autre tracing compatible.
  • Export des traces au format JSON (ex. Jaeger, Zipkin, ou fichier local).
  • Fichier OpenAPI au format YAML ou JSON accessible.

2.2 Étapes du script (Python)

  1. Charger le schéma OpenAPI
  2. Parser les traces et extraire les chemins réels.
  3. Normaliser les chemins (remplacer les IDs par {param}).
  4. Comparer chaque chemin normalisé aux chemins du schéma.
  5. Lister les chemins non trouvés.
import yaml, json, re
from pathlib import Path

def load_openapi(path):
    return yaml.safe_load(Path(path).read_text())

def extract_paths_from_traces(trace_file):
    traces = json.loads(Path(trace_file).read_text())
    paths = set()
    for span in traces:
        url = span.get('http.url') or span.get('url')
        if url:
            # garder uniquement le chemin
            path = re.sub(r'^https?://[^/]+', '', url)
            paths.add(path)
    return paths

def normalize(path):
    # remplace les segments numériques par {param}
    return re.sub(r'\d+', '{param}', path)

def find_undocumented(openapi_path, trace_path):
    spec = load_openapi(openapi_path)
    spec_paths = set(spec['paths'].keys())
    traced = {normalize(p) for p in extract_paths_from_traces(trace_path)}
    undocumented = traced - spec_paths
    return undocumented

if __name__ == '__main__':
    undocumented = find_undocumented('openapi.yaml', 'traces.json')
    for ep in sorted(undocumented):
        print(f'Endpoint non documenté : {ep}')

2.3 Explication du code

  • load_openapi : lit le fichier openapi.yaml et le transforme en dictionnaire Python.
  • extract_paths_from_traces : parcourt chaque span, récupère l’URL, puis ne conserve que le chemin.
  • normalize : remplace les identifiants numériques par un placeholder {param} afin de matcher les routes paramétrées.
  • find_undocumented : réalise la différence entre les chemins tracés et ceux du schéma.

3. Analyse des résultats et bonnes pratiques

3.1 Interpréter la liste

  • Endpoints legacy : routes conservées pour la compatibilité mais oubliées du spec. Décidez de les déprécier ou de les documenter.
  • Routes temporaires : créées lors de tests A/B. Supprimez‑les si elles ne sont plus utiles.
  • Erreurs de routing : chemins mal configurés (ex. /api/v1//users). Corrigez la configuration du serveur.

3.2 Actions recommandées

  • Mettre à jour le schéma dès qu’un endpoint apparaît dans les traces.
  • Automatiser le processus via un CI/CD qui exécute le script à chaque déploiement.
  • Intégrer les résultats dans le tableau de bord Lescopr : visualisez les endpoints non documentés en temps réel.

3.3 Checklist rapide

  • Traces exportées au format JSON ?
  • Schéma OpenAPI versionné et accessible ?
  • Script exécuté dans le pipeline CI ?
  • Alertes configurées sur les nouvelles divergences ?

4. Cas d’usage typique : API de paiement

Une plateforme de paiement utilise FastAPI pour exposer /payments, /refunds et /transactions. Après plusieurs itérations, des appels à /payments/v2/legacy/confirm apparaissent dans les logs mais ne figurent pas dans le spec. En appliquant le script :

  1. Le script détecte 3 endpoints non documentés.
  2. L’équipe décide de déprécier /payments/v2/legacy/confirm et de documenter /payments/v2/confirm.
  3. Le MTTR passe de 45 minutes à 12 minutes grâce à une visibilité immédiate.

5. Intégration avec Lescopr

Lescopr propose une pipeline d’observabilité qui consomme directement les sorties du script ci‑dessus. Les endpoints orphelins sont affichés sur un tableau de bord dédié, avec des filtres par version, par service et par SLA. Vous pouvez ainsi :

  • Prioriser les corrections selon l’impact business.
  • Auditer la conformité RGPD en s’assurant que chaque route est décrite.
  • Automatiser la mise à jour du schéma via des webhooks vers votre dépôt Git.

Conclusion

La corrélation entre traces et spec OpenAPI est le levier le plus efficace pour éliminer les endpoints non documentés dans les applications FastAPI. En automatisant ce processus, vous réduisez le MTTR, améliorez la conformité et renforcez la confiance des équipes SRE.

Pour aller plus loin, la documentation Lescopr détaille la mise en place pas à pas.