Versioning your API is crucial for maintaining backward compatibility as your application evolves. FastAPI makes API versioning straightforward, and with some attention to your project structure, you can maximize reusability and flexibility for future iterations.
Why Version Your API?
API versioning allows you to make breaking changes to your endpoints while ensuring existing clients are not disrupted. A common approach is to prefix routes with the version (for example, /api/v1
and /api/v2
).
Suggested Project Structure
A clean directory structure helps with maintainability, especially as more versions and endpoints get added. Here’s a setup that works well for most FastAPI projects:
my_fastapi_project/
├── app/
│ ├── api/
│ │ ├── v1/
│ │ │ ├── endpoints/
│ │ │ │ └── users.py
│ │ │ └── __init__.py
│ │ ├── v2/
│ │ │ ├── endpoints/
│ │ │ │ └── users.py
│ │ │ └── __init__.py
│ │ └── __init__.py
│ ├── core/
│ │ ├── config.py
│ │ └── __init__.py
│ ├── main.py
│ └── __init__.py
├── .venv/
├── requirements.txt
└── README.md
Key Points:
- Place each API version in its own folder (
app/api/v1/
,app/api/v2/
), with a further split for endpoints. This keeps versioned code separated but allows sharing non-breaking, reusable code (models, dependencies) in common folders. core/
directory is a great spot for application-wide settings, configs, and shared logic.- Python environment directory (
.venv/
) should be at the project root and is usually gitignored to avoid leaking local dependencies. - Dependency management: Track dependencies in
requirements.txt
at the project root for easy installation viapip install -r requirements.txt
. - Main app entry point:
app/main.py
(contains the FastAPI app instance and version router mounting).
Example: Mounting Routers
Here’s how you can mount your API versions in app/main.py
:
from fastapi import FastAPI
from app.api.v1.endpoints import users as users_v1
from app.api.v2.endpoints import users as users_v2
app = FastAPI()
app.include_router(users_v1.router, prefix="/api/v1/users", tags=["users-v1"])
app.include_router(users_v2.router, prefix="/api/v2/users", tags=["users-v2"])
Each users.py
in v1
or v2
will define a FastAPI router and version-specific endpoints.
Reusing Logic
Models, schemas, and utility functions should live in commonly-imported modules (e.g., app/core/
or app/models/
). For versioned logic that is mostly unchanged, consider importing from a previous version and extending or overriding as needed in the new version.
Summary
Organizing your FastAPI project for API versioning helps you:
- Prevent code duplication
- Encourage refactoring and reuse
- Make transitions between API versions smooth for both developers and clients
Always keep your development environment (.venv
), dependency files (requirements.txt
), and documentation at the root for accessibility and maintainability.
Leave a Reply