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.
To run it locally, clone the repository and execute the following command:
git clone https://github.com/feodor-ra/fastapi-easy-versioning.git
uvx --python=3.14 --from="fastapi[standard]" --with="fastapi-easy-versioning" fastapi dev fastapi-easy-versioning/examples/simple_versioning.py
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)"]
B --> B2["/another-endpoint ✓"]
C --> C1["/endpoint ✓<br/>(until=2)"]
C --> C2["/another-endpoint ✓"]
C --> C3["/new-another-endpoint ✓"]
D --> D1["/endpoint ✗<br/>(until=2)"]
D --> D2["/another-endpoint ✓<br/>(overridden in v3)"]
D --> D3["/new-another-endpoint ✓"]
style B1 fill:#90EE90
style B2 fill:#90EE90
style C1 fill:#90EE90
style C2 fill:#90EE90
style C3 fill:#90EE90
style D1 fill:#FFB6C1
style D2 fill:#90EE90
style D3 fill:#90EE90
classDef available fill:#90EE90,stroke:#333;
classDef notAvailable fill:#FFB6C1,stroke:#333;