An issue is raised when a router prefix is defined in the include_router() call instead of in the APIRouter() initialization.

Why is this an issue?

In FastAPI applications, routers help organize endpoints into logical groups. Each router can have a URL prefix that gets prepended to all its routes.

When you define the prefix in the include_router() call, the router’s URL structure is separated from its definition. This means developers need to search through the application setup code to understand where the router’s endpoints will be accessible.

Modern FastAPI versions support defining the prefix directly in the APIRouter() constructor. This approach keeps the router’s configuration self-contained and makes the code easier to understand at a glance.

By defining the prefix at initialization time, you create a single source of truth for the router’s configuration. Anyone reading the router file immediately knows its URL structure without having to trace through the application setup.

What is the potential impact?

This pattern reduces code maintainability and readability. In larger applications with multiple routers, it becomes increasingly difficult to understand the application’s URL structure without examining the main application file.

When routers are defined in separate modules (a common practice), developers working on a specific router module cannot see its full URL path without switching to a different file. This cognitive overhead slows down development and increases the likelihood of mistakes when adding or modifying routes.

How to fix it

Move the prefix parameter from the include_router() call to the APIRouter() initialization. This makes the router’s URL structure immediately visible in its definition.

Code examples

Noncompliant code example

from fastapi import APIRouter, FastAPI

router = APIRouter()  # Noncompliant

@router.get("/users")
def list_users():
    return ["user1", "user2"]

app = FastAPI()
app.include_router(router, prefix="/api/v1")

Compliant solution

from fastapi import APIRouter, FastAPI

router = APIRouter(prefix="/api/v1")

@router.get("/users")
def list_users():
    return ["user1", "user2"]

app = FastAPI()
app.include_router(router)

Resources

Documentation