fastapi-class-router-contract
FastAPI HTTP routes 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. Compose the application with FastAPI.include_router(...) instead of declaring HTTP handlers directly on it.
Examples
from fastapi import FastAPI
app = FastAPI()
@app.get("/items", response_model=ItemsResponse)def items() -> ItemsResponse: return ItemsResponse(items=[])from fastapi import FastAPI
app = FastAPI()app.include_router(ItemRouter(service).build())from fastapi import APIRouter
router = APIRouter()from fastapi import APIRouter
class ItemRouter: def __init__(self, service: Service) -> None: self._service = service
def build(self) -> APIRouter: router = APIRouter() return router