Python Friday #242: API Versioning in FastAPI

Last week we created a breaking change when we added the new filter syntax. With API versioning we try to prevent that and make the breaking changes in a different version of an endpoint. There are many ideas on how to version endpoints the correct way, but so far there is no standard that we can follow. In this post we explore 3 approaches to learn the options we have in FastAPI.

This post is part of my journey to learn Python. You find the code for this post in my PythonFriday repository on GitHub.

 

Mark old endpoints as depreciated

When we talk about versioning, we usually have endpoints that people no longer should use. We can use the built-in feature of FastAPI and add the parameter deprecated=True to the endpoints that we want to remove in the future. The endpoint still works as expected, but the documentation shows that its end is near:

When we mark an endpoint with deprecated=True, the documentation shows this endpoint with a warning and the name is crossed out.

That way new users know what endpoints they can use and which they should ignore.

 

Use the routers multiple times

Danilo Reitano explains in his article FastAPI Versioning a simple, yet elegant solution to the versioning problem. We can include our routers multiple times in the same application and put the version into the route:

This let us access our endpoints with these 3 URLs:

  1. /api/todo
  2. /api/v1/todo
  3. /api/latest/todo

The first URL is the same we already have. Therefore, no one needs to change their client when we introduce our versioning schema.
The second URL with v1 will stay on our current version and we will not make any changes there.
The third URL will always point to the latest version. If we introduce a new version, this URL will point to the new endpoints.

If we change our existing endpoints, we can create a routers/todo_v2.py file and include it in our application like this:

Depending on how many clients still use /api/todo/, we may keep it at the initial version, remove it or let it point to the newest version. This is entirely up to us, and we can do what helps us the most.

While this is an easy approach, the more versions you must maintain, the more of a mess it gets.

 

Stripe-like API versioning

If you want to keep hundreds of versions around, you need a different approach than copying router files around. The financial service provider Stripe is well-known for their long support of their many API versions. Stripe wrote about their approach in APIs as infrastructure: future-proofing Stripe with versioning where the data is transformed from the current version to the version the client uses. This allows Stripe to keep all old versions around while they still can maintain their application.

If you want to use this approach with FastAPI, you can use the package Cadwyn. The tutorial explains how you need to setup your project so that Cadwyn can generate the code for the different versions.

This approach takes a lot more work to start, but when you need to maintain versions for years to come, that initial extra effort will be worth it.

 

fastapi-versionizer

Somewhere in the middle of the other two approaches is the fastapi-versionizer package. It is a successor of the no longer maintained package fastapi-versioning that many articles still recommend.

You can install the package with this command:

This minimalistic application shows the main parts of how versioning works with fastapi-versionizer:

If we go to the /docs endpoint, we can see the generated routes for the code above:

The status endpoint shows up in every version, while the hello endpoint v1 is depreciated and we only should use v2 or latest.

The /status endpoint has no version tag and shows up in /v1, /v2, and /latest. Our hello endpoint in /v1 is depreciated and we only should use /v2 or /latest.

If you have multiple endpoints that did not change between versions, you may be better off with fastapi-versionizer than rolling your own versioning schema.

 

Next

There are many ways to define a version for your FastAPI endpoints. The three options we have explored in this post are a good starting point and should help you with the first steps.

Next week we explore our options to limit the number of calls to our API.

1 thought on “Python Friday #242: API Versioning in FastAPI”

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.