Backend Python & FastAPI — des API modernes et évolutives
FastAPI est le framework Python de référence pour les API REST asynchrones. Il associe les annotations de types natives de Python à une validation automatique par Pydantic, à une documentation OpenAPI générée seule et à une exécution ASGI asynchrone — sans sacrifier la lisibilité du code.
FastAPI — un framework Python asynchrone
FastAPI s'exécute sur Uvicorn (serveur ASGI), avec Gunicorn pour le mode multi-processus en production. Un point d'entrée simple qui lit dans le cache Redis. L'injection de dépendances native permet de tester chaque couche isolément sans mocks compliqués : l'authentification, la session de base de données ou la limitation de débit sont chacune une dépendance injectable.
La documentation OpenAPI 3.1 est générée automatiquement à partir des annotations de types — Swagger UI et ReDoc sont disponibles sur `/docs` et `/redoc` en développement. Le schéma Pydantic v2 (validateur écrit en Rust) valide les requêtes et les réponses. Tout champ invalide renvoie un 422 accompagné de messages d'erreur clairs et localisés.
- async/await natif — des entrées-sorties non bloquantes sur toutes les opérations base de données et HTTP
- BackgroundTasks pour le travail postérieur à la réponse (e-mail, webhook, journalisation)
- Prise en charge native des WebSocket pour les fonctions temps réel (chat, notifications)
- Limitation de débit avec slowapi (basée sur limits) — par IP et par utilisateur
- Middlewares CORS, compression (gzip/brotli), identifiant de requête et mesure du temps
PostgreSQL, SQLAlchemy et Alembic
Nous utilisons SQLAlchemy 2.0 async (pilote asyncpg) pour toutes les opérations de base de données. Les modèles sont définis avec des Mapped types — typés sûrement, sans chaînes de caractères. Les requêtes complexes s'écrivent en SQLAlchemy Core (vérifié à la compilation) ou en SQL pur via `text()` avec des paramètres liés — jamais par interpolation de chaînes, ce qui écarte totalement le risque d'injection SQL.
Les migrations Alembic sont générées automatiquement à partir des changements de modèle, puis relues à la main avant application. Chaque migration dispose d'un `upgrade()` et d'un `downgrade()` testés. En production, les migrations s'exécutent en CI avant le déploiement — la base reste donc toujours synchronisée avec le code. Le pool de connexions est géré par asyncpg, avec une taille configurable par service.
- Verrouillage au niveau de la ligne avec `SELECT ... FOR UPDATE` pour les opérations concurrentes critiques
- Recherche plein texte avec pg_trgm et tsvector — sans Elasticsearch pour les cas simples
- JSONB pour les données semi-structurées, avec index GIN
- Tables partitionnées pour les tables de plusieurs millions de lignes (journaux, événements)
Cache Redis et montée en charge horizontale
Redis 7 sert de cache applicatif (TTL par point d'entrée), de magasin de sessions (jetons de rafraîchissement JWT avec révocation sélective), de pub/sub pour les événements temps réel et de file d'attente pour les traitements de fond (Celery ou ARQ). La stratégie de cache est de type cache-aside avec invalidation explicite — pas un TTL aveugle qui risquerait de servir des données périmées.
- Authentification JWT avec jeton d'accès (15 min) et jeton de rafraîchissement en Redis (7 jours)
- Celery avec Redis comme broker pour les tâches asynchrones (génération de PDF, e-mails, imports)
- Point d'entrée de health check `/health` indiquant l'état de la base, de Redis et la version déployée
- Journalisation structurée en JSON (structlog) — compatible avec Loki, Datadog et ELK
Avantages et limites
Avantages
- Une exécution ASGI asynchrone pour les entrées-sorties.
- Une documentation OpenAPI générée automatiquement à partir des annotations de types.
- Une validation Pydantic v2 rapide, avec des erreurs 422 explicites.
- Un code lisible : Python est familier à la plupart des équipes.
Limites
- Python reste plus lent que Go ou Rust sur les tâches gourmandes en CPU.
- async/await exige de la rigueur — un seul appel bloquant fige toute la boucle d'événements.
- Un écosystème plus jeune que Django pour les fonctionnalités livrées clés en main.
- Ni ORM ni interface d'administration intégrés — ils se choisissent séparément.
Verdict en bref
Choisissez FastAPI pour des API REST asynchrones, des microservices et des backends de SPA ou d'applications mobiles. Pour des traitements extrêmement gourmands en CPU ou pour un monolithe avec administration prête à l'emploi, Go et Django seront respectivement plus adaptés.
Tableau des spécifications
| Capacité | Limite / seuil | Usage courant | |
|---|---|---|---|
| Concurrence | async/await, entrées-sorties non bloquantes | Les traitements CPU nécessitent des workers séparés | API multipliant les appels base de données et HTTP |
| Latence | Cache Redis par point d'entrée | Augmente avec la sérialisation de gros payloads | Backends SaaS, mobiles et temps réel |
| Validation & documentation | Pydantic v2 et OpenAPI 3.1 automatique | Des schémas complexes rallongent le démarrage | API publiques avec Swagger ou ReDoc |
| Coût courant | Open source, fonctionne sur 1 vCPU | La montée en charge horizontale demande plusieurs processus | Du MVP à la production |
FastAPI face aux alternatives
| Critère | FastAPI | Django / Express |
|---|---|---|
| Performances asynchrones | Excellentes (ASGI natif) | Django partiellement, Express bonnes |
| Documentation OpenAPI automatique | Oui, depuis les annotations de types | Nécessite des paquets supplémentaires |
| Administration / ORM intégrés | Non (à choisir séparément) | Django : oui ; Express : non |
Questions fréquentes
FastAPI est-il plus rapide que Django ?
Sur les entrées-sorties, oui. FastAPI s'exécute de façon asynchrone sur ASGI et absorbe donc bien plus de requêtes concurrentes comportant des appels base de données ou HTTP que le Django synchrone classique. Django, en revanche, embarque davantage de fonctionnalités d'origine.
À quoi FastAPI ne convient-il pas ?
Pour les tâches très gourmandes en CPU (traitement d'images, calcul numérique lourd), Python est plus lent que Go ou Rust ; ces traitements sont déportés sur des workers séparés. Et FastAPI ne fournit pas d'interface d'administration prête à l'emploi comme Django.
FastAPI a-t-il besoin d'un ORM ?
Pas obligatoirement. Nous utilisons SQLAlchemy 2.0 async avec Alembic pour les migrations, mais du SQL pur reste possible. L'ORM n'est pas inclus : vous le choisissez selon le projet.
Comment faire monter en charge un backend FastAPI ?
Horizontalement : on lance plusieurs processus Uvicorn sous Gunicorn, derrière un répartiteur de charge, avec un cache Redis et les traitements lourds déportés sur Celery. La conception sans état permet d'ajouter des instances au besoin.