Versioning of a FastAPI application

Versioning of a FastAPI application

Version your FastAPI application with independent docs for each api versions

Hi everyone! In this blog post, I'm going to show you how to implement versioning for a FastAPI application with independent docs for each version. This is useful if you want to maintain different versions of your API with different features and functionality, and also provide clear and consistent documentation for each version.

FastAPI is a modern web framework that makes it easy to build fast and reliable APIs with Python. It has a lot of features that make it a great choice for developing RESTful APIs, such as automatic validation, documentation, testing, dependency injection, and more. If you haven't tried it yet, I highly recommend you check it out.

One of the cool features of FastAPI is that it automatically generates interactive documentation for your API using OpenAPI and Swagger UI. You can access the documentation by visiting the /docs endpoint of your application. For example, if your application is running on http://localhost:8000, you can go to http://localhost:8000/docs to see the documentation.

However, what if you want to have multiple versions of your API with different endpoints, parameters, and responses? For example, you might want to have a v1 version that supports some basic functionality, and a v2 version that adds some new features or changes some existing ones. How can you manage the versioning and documentation of your API simply and elegantly?

Two possible solutions

First approach

One possible solution is to use path parameters to define the version of your API. For example, you can have /v1/users and /v2/users as different endpoints for different versions of your API. This way, you can use the same FastAPI app object to handle all the versions and use dependency injection to pass the version as an argument to your functions.

However, this approach has some drawbacks. First of all, it makes the documentation more cluttered and confusing, as all the versions are mixed on the same page. Secondly, it makes it harder to maintain backward compatibility and deprecate older versions, as you have to keep track of all the changes and differences between the versions in your code.

The second approach (The better one)

A better solution is to use sub-applications to separate each version of your API into its own app object. This way, you can have more control and flexibility over each version and also have independent documentation for each version. For example, you can have /v1/docs and /v2/docs as different endpoints for different versions of your documentation.

To implement this solution, you need to do the following steps:

  1. Create a main app object using FastAPI.

  2. Create sub-app objects for each version of your API using FastAPI.

  3. Define the endpoints and logic for each version using the sub-app objects.

  4. Mount the sub-app objects to the main app object using a prefix that indicates the version.

  5. Run the main app object using uvicorn or any other ASGI server.

Here is an example of how this would look like in code:

# Import FastAPI
from fastapi import FastAPI

# Create main app object
app = FastAPI()

# Create sub-app objects for each version
app_v1 = FastAPI()
app_v2 = FastAPI()

# Define endpoints and logic for v1
@app_v1.get("/users")
def get_users_v1():
# Return some dummy data
return [{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}]

# Define endpoints and logic for v2
@app_v2.get("/users")
def get_users_v2():
# Return some dummy data with a new field
return [{"name": "Alice", "age": 25, "email": "alice@example.com"}, {"name": "Bob", "age": 30, "email": "bob@example.com"}]

# Mount sub-apps to main app with prefixes
app.mount("/v1", app_v1)
app.mount("/v2", app_v2)

Now, if you run this code with any server like uvicorn and visit http://localhost:8000/v1/docs or http://localhost:8000/v2/docs, you will see independent documentation for each version of your API.

In case if you would like to describe your sub applications you can pass some arguments to the FastAPI instance this way

# Create the sub-application for the first version
app_v1 = FastAPI(
title="My API v1",
description="The first version of my API",
docs_url="/v1/docs",
redoc_url="/v1/redoc",
)

# Create the sub-application for the second version
app_v2 = FastAPI(
title="My API v2",
description="The second version of my API",
docs_url="/v2/docs",
redoc_url="/v2/redoc",
)

This way, you can easily manage the versioning and documentation of your FastAPI application with sub-applications. I hope you found this blog post helpful and informative. If you have any questions or feedback, feel free to leave a comment below. Thanks for reading!

Did you find this article valuable?

Support Sai Lokesh Reddy by becoming a sponsor. Any amount is appreciated!