Simple Versioning Example¶
The example demonstrates the basic scenario: three versions of one API, availability limited with until, endpoint inheritance, reading metadata via VersionInfo and redefining an endpoint in a newer version.
The example code is on GitHub.
Run it locally
The example contains the following code:
from typing import Annotated
from fastapi import Depends, FastAPI, middleware
from fastapi_easy_versioning import (
VersionInfo,
VersioningMiddleware,
versioning,
)
app = FastAPI(middleware=[middleware.Middleware(VersioningMiddleware)])
app_v1 = FastAPI(api_version=1)
app_v2 = FastAPI(api_version=2)
app_v3 = FastAPI(api_version=3)
app.mount("/v1", app_v1)
app.mount("/v2", app_v2)
app.mount("/v3", app_v3)
@app_v1.get("/endpoint", dependencies=[Depends(versioning(until=2))])
def endpoint() -> str:
return "I'm v1 endpoint"
@app_v1.get("/another-endpoint")
def another_endpoint(
version: Annotated[VersionInfo, Depends(versioning())],
) -> str:
return f"I'm v{version.origin} another endpoint"
@app_v2.get("/new-another-endpoint", dependencies=[Depends(versioning())])
def new_another_endpoint() -> str:
return "I'm v2 new another endpoint"
@app_v3.get("/another-endpoint", dependencies=[Depends(versioning())])
def overload_another_endpoint() -> str:
return "I'm v3 overloaded another endpoint"
This code creates three API versions (v1, v2, v3), with Swagger documentation available at:
The resulting structure is as follows:
- The first version includes two endpoints:
/endpoint, available in versions v1 and v2 (withuntil=2restriction)-
/another-endpoint, available across all versions (v1, v2, and v3) -
The second version introduces a new endpoint
/new-another-endpoint, available in all versions starting from v2 (v2 and v3) -
The third version adds an endpoint
/another-endpointthat overrides the same-named endpoint from the first version and will be available in all subsequent versions
graph TD
A[Endpoint Availability] --> B[v1<br/>api_version=1]
A --> C[v2<br/>api_version=2]
A --> D[v3<br/>api_version=3]
B --> B1["/endpoint ✓<br/>(until=2)"]:::available
B --> B2["/another-endpoint ✓"]:::available
C --> C1["/endpoint ✓<br/>(until=2)"]:::available
C --> C2["/another-endpoint ✓"]:::available
C --> C3["/new-another-endpoint ✓"]:::available
D --> D1["/endpoint ✗<br/>(until=2)"]:::missing
D --> D2["/another-endpoint ✓<br/>(overridden in v3)"]:::available
D --> D3["/new-another-endpoint ✓"]:::available
classDef available fill:#90EE90,stroke:#333,color:#1b1b1b
classDef missing fill:#FFB6C1,stroke:#333,color:#1b1b1b