Skip to main content
In this lesson, we explore a common pitfall related to route ordering in FastAPI. FastAPI matches incoming requests based on the defined routes, and the sequence in which the routes are declared is crucial for ensuring that each request is handled by its intended endpoint. Misordering routes can lead to unexpected behavior.

Retrieving a Post by ID

Below is a simple GET endpoint that retrieves a post by its ID. When a request is made to this route, it prints and returns the corresponding post details.

Sample Console Output

Introducing the Latest Post Endpoint

Now, consider adding another GET endpoint intended to retrieve the latest post. The goal is to process a request to /posts/latest and return the most recent post.

An Initial Attempt

The following handler is an initial attempt to implement this functionality:

Console Output for the Initial Attempt

Evolving the Code

The code evolves to determine the latest post by subtracting one from the length of the posts list. In this version, the routes are defined as follows:

Console Output Remains Similar

Storing and Returning the Latest Post

After further modifications, the code tries to store the latest post in a variable and return it:
The logging output still remains the same:

The Corrected Latest Post Route

A new test call is made by copying the URL from a previous request. The updated code now looks like this:

Console Output for the Updated Code

The Route Conflict Issue

If you change the request URL to /posts/latest, you might see the following error response:
This error occurs because FastAPI processes routes in the order they are defined. The route /posts/{id} appears before /posts/latest, causing the string “latest” to be interpreted as the integer parameter id. Since “latest” is not an integer, FastAPI throws a type validation error.

Illustrative Route Definitions

Consider the following set of route definitions that illustrate the issue:
In this configuration, the route /posts/{id} catches any requests to /posts/..., including /posts/latest, because “latest” fits the dynamic segment {id}. FastAPI attempts to convert “latest” to an integer, resulting in the error.

Correcting the Route Order

To resolve this issue, ensure that the specific route (/posts/latest) is declared before the dynamic route (/posts/{id}). Here is the corrected ordering:
With this ordering, a GET request to /posts/latest is handled correctly by its dedicated endpoint, while requests for posts by integer ID are processed separately.

Example Responses

When accessing a specific post by its ID, a successful response might look like this:
For the latest post endpoint, a successful response might appear as follows:
Remember that FastAPI evaluates routes in the order they are added. Always define fixed routes (e.g., /posts/latest) before dynamic ones (e.g., /posts/{id}) to prevent unintended matches and to avoid type validation errors.
For more information on FastAPI routing, check out the FastAPI Documentation.

Watch Video