Skip to content

fastapi-class-router-contract

FastAPI routers use injected *Router.build() owners and explicit named object response models.

Why

Class-owned construction gives dependencies one reviewable composition boundary, while explicit object models keep success envelopes stable and generated clients precise.

Fix

Inject dependencies through *Router.__init__, create and return a local APIRouter from build(), and declare response_model=NamedResponse with a matching named return annotation.

Examples

Before — flagged A module owns an unscoped router
app/routes.py
from fastapi import APIRouter
router = APIRouter()
After — preferred A class builds and returns its router
app/routes.py
from fastapi import APIRouter
class ItemRouter:
def __init__(self, service: Service) -> None:
self._service = service
def build(self) -> APIRouter:
router = APIRouter()
return router