Aller au contenu

Deep Dive API

Cette page explique comment penser une API FastAPI dans Arclith.

Position

L'API est un adapter inbound. Elle reçoit HTTP, valide le contrat externe, puis appelle un port inbound ou un use case.

Text Only
1
2
3
4
5
6
HTTP request
  -> FastAPI route
  -> schéma d'entrée
  -> use case
  -> schéma de sortie
  -> HTTP response

La route ne contient pas la règle métier. Elle traduit un protocole.

Création De L'application

Python
1
2
3
4
from arclith import Arclith

arclith = Arclith("config")
app = arclith.fastapi()

Arclith.fastapi() applique les conventions transverses disponibles: configuration de l'application, middlewares HTTP, instrumentation OpenTelemetry si activée, et patch Swagger OAuth2 quand Keycloak est configuré.

Route Propre

Une route propre fait trois choses:

  1. valider l'entrée HTTP;
  2. appeler le use case;
  3. convertir le résultat en réponse HTTP.
Python
1
2
3
4
5
@router.post("/", status_code=201)
async def create_todo(payload: CreateTodoRequest) -> TodoResponse:
    command = payload.to_command()
    todo = await create_todo_use_case.execute(command)
    return TodoResponse.from_entity(todo)

Le use case ne doit pas recevoir Request, Response, Depends, HTTPException ou un repository concret.

Auth Et Licence

Python
1
2
3
4
5
6
7
8
from fastapi import APIRouter, Depends

require_auth = arclith.auth_dependency()

router = APIRouter(
    prefix="/v1/todos",
    dependencies=[Depends(require_auth)],
)

Le pipeline JWT peut aussi vérifier la capability license si elle est configurée. Une erreur d'authentification donne 401; une licence manquante donne 403.

Multitenant

En mode multitenant, brancher la dépendance de résolution tenant sur les routes qui accèdent à un repository multitenant. Le tenant vient d'un claim JWT signé, puis les coordonnées techniques sont résolues via les resolvers configurés.

Le handler API ne doit pas accepter une URI tenant depuis le client.

HTTP Transverse

Les concerns HTTP transverses restent dans la capability HTTP:

Concern Rôle
idempotence sécuriser les retries de commandes
ETag gérer les lectures conditionnelles
Cache-Control expliciter le comportement de cache client
timing mesurer la latence des routes

Observabilité

Quand les probes sont activées, séparer le port métier du port d'observation.

Python
arclith.run_with_probes(lambda: arclith.run_api("main:app"), transports=["api"])

Le port API sert /v1/.... Le port probe sert /health, /ready, /info et /metrics.

Erreurs Fréquentes

Erreur Correction
route qui instancie un repository injecter un use case déjà câblé
HTTPException dans le domaine lever une erreur métier puis convertir en API
secret dans le schéma de réponse filtrer dans TodoResponse.from_entity
Swagger auth ambigu vérifier la config Keycloak et client_id
healthcheck sur le port API utiliser le port probe si run_with_probes est actif

Validation

Bash
1
2
3
4
MODE=api uv run python main.py
curl -fsS http://127.0.0.1:9000/health
curl -fsS http://127.0.0.1:8000/docs
uv run pytest

Un test API minimal doit vérifier le statut, le JSON de sortie et l'appel réel du use case avec une dépendance de test.

Pages Liées

Média

Média à produire

Capture : Swagger UI avec auth activée. Vidéo : route FastAPI qui appelle un use case.