FastAPI : bâtir une API REST en Python sans se noyer dans la plomberie
Le reste — la validation, la sérialisation JSON, la documentation, les codes d'erreur — il s'en occupe. La question n'est pas de savoir si c'est agréable au début. Ça l'est. La question est de savoir ce que ça te coûte plus tard, quand ton API aura trente routes et deux développeurs de plus.
Ce que FastAPI fait vraiment
FastAPI s'appuie sur deux briques : Starlette pour la couche HTTP et ASGI, Pydantic pour la validation et le parsing des données. Il tourne sur Python 3.7 et plus, mais en pratique tu voudras 3.10 ou plus récent, ne serait-ce que pour les syntaxes de types modernes.Ces deux dépendances ne sont pas un détail d'implémentation. Elles déterminent tout ce que tu pourras ou ne pourras pas faire.
Starlette gère les requêtes, les websockets, le streaming, le middleware. C'est léger, et c'est asynchrone de bout en bout. Pydantic, lui, lit tes annotations de type et construit un validateur à partir d'elles. Tu écris `age: int`, Pydantic refuse tout ce qui n'est pas un entier. Tu n'écris aucune ligne de vérification.
C'est là que le framework gagne du temps. Pas dans les benchmarks, dans les `if` que tu n'écris pas.
La performance, mise en perspective
FastAPI est rapide. Sur des charges I/O-bound — requêtes base de données, appels à des services externes — il tient la comparaison avec des frameworks Node.js, et il reste dans le voisinage de ce que fait Go sur certains scénarios.Ce chiffre veut dire quelque chose de précis : quand ton endpoint attend une réponse de PostgreSQL, la boucle d'événements peut servir d'autres requêtes pendant ce temps. Pas de thread bloqué, pas de pool à dimensionner.
Mais attention au mot « rapide ». Si ton goulot d'étranglement est une requête SQL mal indexée, FastAPI ne t'aidera pas. Il ne rendra pas ton code plus rapide que ce qu'il fait. Il rend juste l'attente moins coûteuse.
La vraie question, c'est : est-ce que ton endpoint passe son temps à attendre ou à calculer ? S'il calcule, `async` ne t'apportera rien et te coûtera même un peu.
La documentation qui se maintient toute seule
Chaque route que tu déclares alimente un schéma OpenAPI. Ce schéma alimente une interface Swagger UI, accessible par défaut sur `/docs`.Tu ouvres cette page, tu vois tes endpoints, tu peux les appeler depuis le navigateur. La documentation est générée à partir du code, pas écrite à côté.
C'est un avantage réel, et une contrainte réelle. Si tes types sont mal définis, ta documentation sera fausse. FastAPI ne devine pas ton intention, il lit tes annotations. Une annotation approximative donne une documentation approximative, avec l'autorité tranquille d'un schéma OpenAPI.
Il existe aussi une interface ReDoc sur `/redoc`, plus lisible pour parcourir une API large. Les deux sortent du même schéma.
Pydantic, ou l'endroit où tu décides de tes contrats
Un modèle Pydantic, c'est une classe avec des champs typés. Tu l'utilises pour décrire ce qui entre et ce qui sort.```python from pydantic import BaseModel
class Utilisateur(BaseModel): nom: str age: int email: str | None = None ```
Si une requête envoie `age: "vingt"`, FastAPI retourne un 422 avec un message qui indique le champ fautif et la raison. Tu n'as rien écrit pour ça.
Le coût, c'est la rigidité. Chaque changement de contrat passe par le modèle. Tu ne peux pas bricoler un champ en route sans casser la validation. C'est exactement ce qu'on veut sur une API publique. C'est parfois pénible sur un prototype jetable.
Async : à utiliser quand ça sert
FastAPI accepte les deux styles. Une fonction `def` classique tourne dans un threadpool. Une fonction `async def` tourne dans la boucle d'événements.Tu peux mélanger les deux dans le même projet. Tu ne peux pas appeler du code bloquant depuis une coroutine sans bloquer la boucle pour tout le monde.
C'est la principale source d'erreurs de performance avec FastAPI. Une bibliothèque synchrone utilisée dans un `async def` transforme ton serveur en file d'attente. Le symptôme est clair : tout va bien en développement, tout s'écroule en production dès qu'il y a du trafic.
Si tu ne sais pas si une dépendance est async, suppose qu'elle ne l'est pas.
Dependency injection : utile, pas magique
FastAPI te permet de déclarer des dépendances — authentification, session base de données, paramètres de configuration — et de les injecter dans tes endpoints.```python from fastapi import Depends, HTTPException
async def utilisateur_courant(token: str = Depends(verifier_token)): if not token_valide(token): raise HTTPException(status_code=401, detail="Non autorisé") return charger_utilisateur(token)
@app.get("/profil") async def profil(user = Depends(utilisateur_courant)): return user ```
Le mécanisme est propre. La logique d'authentification vit à un seul endroit. Les endpoints qui en ont besoin la déclarent, les autres l'ignorent.
Là où ça se complique, c'est quand les dépendances s'appellent entre elles sur plusieurs niveaux. Tu obtiens un graphe qui n'est visible nulle part, et un endpoint qui déclenche cinq appels que tu ne vois pas dans sa signature.
Ce n'est pas un défaut du framework. C'est un défaut de discipline, et FastAPI ne t'empêchera pas d'en manquer.
Authentification, sécurité : le socle est là
FastAPI fournit les briques pour OAuth2 avec Bearer tokens. Il y a des utilitaires pour JWT, pour hasher les mots de passe, pour valider un token avant d'exécuter un endpoint.Ce sont des briques, pas une solution complète. Tu configures toi-même l'émission des tokens, leur expiration, leur révocation, le stockage des clés. FastAPI ne prend pas ces décisions pour toi.
C'est le bon niveau d'abstraction pour une équipe qui sait ce qu'elle fait. Pour quelqu'un qui découvre l'authentification, c'est un piège classique : le framework donne l'impression que tout est réglé, alors qu'il n'a fait que te donner les outils.
L'écosystème autour
FastAPI s'intègre sans friction avec Docker, ce qui règle la question du déploiement. Il fonctionne avec SQLAlchemy, Tortoise ORM, ou n'importe quel driver de base de données.Il tourne derrière Uvicorn ou Hypercorn en ASGI. En production, tu le places derrière Nginx ou Traefik pour le TLS et la limitation de débit.
Rien de tout cela n'est spécifique à FastAPI. C'est l'écosystème Python côté serveur, et FastAPI s'y insère proprement.
Ce que ça coûte, en clair
FastAPI est simple tant que ton API reste simple. Les modèles Pydantic, les dépendances, les routes décorées : tout tient dans la tête.Au bout de quelques mois, tu as des modèles qui se répondent, des dépendances imbriquées, des schémas OpenAPI qui divergent de ce que tu croyais exposer. Le framework n'a rien fait de mal. Il a juste rendu facile l'ajout de couches, et tu as ajouté des couches.
Django REST Framework, à côté, impose une structure. Tu as des serializers, des viewsets, des routers. C'est plus lourd à démarrer, et ça te force à ranger. Si ton équipe est junior ou nombreuse, cette contrainte peut valoir mieux qu'une liberté qui se paie en dette technique.
Flask, lui, ne te donne rien. Tu assembles. C'est parfait pour un service de trois routes, et intenable pour une API publique maintenue sur cinq ans.
La communauté et la documentation
La documentation officielle de FastAPI est dense et bien faite. Elle couvre les cas courants avec des exemples exécutables, et elle est traduite en plusieurs langues.La communauté est active sur GitHub et Stack Overflow. Les réponses existent pour la plupart des problèmes que tu rencontreras.
Un bémol : la documentation est très liée à la version courante. Un tutoriel de 2021 sur FastAPI 0.68 ne s'applique pas toujours à la 0.115. Vérifie la version avant de copier un exemple.
Ce qui décidera pour toi
Si tu construis une API REST en Python, si ton équipe est à l'aise avec les types et `async`, et si tu veux de la documentation générée sans effort, FastAPI est un choix solide.Si ton équipe est junior, si tu as besoin d'un cadre rigide, ou si ton application est surtout du CRUD avec un back-office, Django REST Framework te coûtera moins cher sur la durée.
Le reste dépend de ce que tu fais tourner derrière. Un framework rapide sur une base de données lente reste une base de données lente.