Skip to content

Guide pratique : versionner son API ​

Séparer les endpoints en /v1, /v2 en utilisant l'APIRouter de FastAPI avec le paramètre prefix.


Structure de base ​

python
from fastapi import APIRouter, FastAPI

app = FastAPI()

v1_router = APIRouter(prefix="/v1", tags=["v1"])
v2_router = APIRouter(prefix="/v2", tags=["v2"])

@v1_router.get("/users")
def list_users_v1() -> list[UserResponseV1]:
    ...

@v2_router.get("/users")
def list_users_v2() -> list[UserResponseV2]:
    ...

app.include_router(v1_router)
app.include_router(v2_router)

Le prefix d'un APIRouter est ajouté automatiquement aux chemins à l'intérieur du router. N'écrivez pas /v1 dans les chemins internes (cela créerait une duplication).


Partager la couche domaine ; absorber les différences de version dans la couche HTTP ​

Gardez la logique partagée entre les versions dans la couche domaine, et exprimez les différences par version dans les modèles Pydantic.

python
# Couche domaine (indépendante de la version)
@dataclass(frozen=True, slots=True)
class User:
    user_id: int
    first_name: str
    last_name: str
    email: str
    age: int

# v1 : fusion en full_name
class UserResponseV1(BaseModel):
    user_id: int
    full_name: str
    email: str

    @classmethod
    def from_domain(cls, user: User) -> "UserResponseV1":
        return cls(
            user_id=user.user_id,
            full_name=f"{user.first_name} {user.last_name}",
            email=user.email,
        )

# v2 : séparation first_name/last_name + ajout age + email → contact_email
class UserResponseV2(BaseModel):
    user_id: int
    first_name: str
    last_name: str
    contact_email: str
    age: int

    @classmethod
    def from_domain(cls, user: User) -> "UserResponseV2":
        return cls(
            user_id=user.user_id,
            first_name=user.first_name,
            last_name=user.last_name,
            contact_email=user.email,
            age=user.age,
        )

Schéma OpenAPI ​

Définir tags=["v1"] / tags=["v2"] sur chaque APIRouter les regroupe par version dans Swagger UI. UserResponseV1 / UserResponseV2 sont définis séparément dans le schéma.


Voir aussi ​

  • FT109 : docs/field-trials/2026-05-field-trial-109.md

Publié sous la licence MIT.