Skip to content

Refactor routing internals into modular components with stable facade#15210

Open
rajratangm wants to merge 8 commits intofastapi:masterfrom
rajratangm:pr1-routing-modularization
Open

Refactor routing internals into modular components with stable facade#15210
rajratangm wants to merge 8 commits intofastapi:masterfrom
rajratangm:pr1-routing-modularization

Conversation

@rajratangm
Copy link
Copy Markdown

Problem
fastapi/routing.py had grown very large and mixed multiple responsibilities (router APIs, route classes, handler factories, low-level wrapper utilities).
This made targeted maintenance, code review, and future refactors harder than necessary.
Goal
Reduce routing complexity without changing public behavior by splitting internals into focused modules while preserving the existing fastapi.routing import surface.
What changed

  1. Public compatibility facade retained
    fastapi/routing.py is now a lightweight compatibility layer that re-exports routing symbols and documents the stability contract.
    Public imports still work as before:
    APIRouter
    APIRoute
    APIWebSocketRoute
    handler/helper exports used by existing tests and extension patterns
    Added explicit all to make export intent and boundaries clearer.
  2. Internal routing modules extracted
    Routing implementation is split into focused files:
    fastapi/routing_router.py
    APIRouter implementation (large router API surface)
    fastapi/routing_routes.py
    APIRoute
    APIWebSocketRoute
    fastapi/routing_handlers.py
    request/websocket handler factories
    handler config object (RouteHandlerConfig)
    fastapi/routing_utils.py
    low-level wrapper and utility helpers (lifespan wrappers, serializer helpers, route wrapper helpers)
  3. Architecture documentation added
    docs/en/docs/advanced/routing-architecture.md
    explains facade vs internal module structure
    clarifies intended stability contract
  4. Contract tests added
    tests/test_routing_facade_contract.py
    verifies expected symbols stay exported from fastapi.routing
    verifies re-export identity for core classes/helpers
    verifies _PING_INTERVAL compatibility exposure
    Behavior compatibility notes
    This PR is intended as a mechanical/structural refactor:
    no intentional API behavior changes
    public import paths remain stable through re-exports
    compatibility for monkeypatch-driven SSE tests preserved via facade export path

Test evidence
_

Executed and passing:
pdm run pytest tests/test_routing_facade_contract.py tests/test_sse.py tests/test_fastapi_cli.py
full suite: pdm run pytest
Result: all expected tests green for this PR scope.
Reviewer guide (low-risk order)
fastapi/routing.py (facade and explicit export contract)
tests/test_routing_facade_contract.py (behavior lock for re-exports)
fastapi/routing_routes.py and fastapi/routing_handlers.py (moved logic)
fastapi/routing_router.py and fastapi/routing_utils.py
docs/en/docs/advanced/routing-architecture.md

_

rajratangm and others added 2 commits March 24, 2026 16:56
Extract APIRouter, APIRoute/APIWebSocketRoute, and handler/util logic into focused modules while preserving `fastapi.routing` public imports via compatibility re-exports and adding routing facade contract tests.

Made-with: Cursor
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 24, 2026

Merging this PR will not alter performance

✅ 20 untouched benchmarks


Comparing rajratangm:pr1-routing-modularization (e414cbb) with master (25a3697)

Open in CodSpeed

@rajratangm
Copy link
Copy Markdown
Author

Could a maintainer please add the label to this PR so the required label check can pass? This PR is a mechanical routing modularization with compatibility facade/re-exports and no intended API behavior change. Thanks!

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 24, 2026

rajratangm and others added 6 commits March 24, 2026 17:18
Exercise IntEnum status normalization and Response return-annotation inference to keep routing refactor coverage at required threshold.

Made-with: Cursor
Normalize request handler typing in routing utils and explicitly type APIRoute.response_field to satisfy mypy and ty hooks.

Made-with: Cursor
Cover both sync and async wrapper paths in request_response to keep aggregate coverage at the repository fail-under threshold.

Made-with: Cursor
Exercise get_request_handler legacy dependant signature and execute raw response helper to close remaining uncovered lines seen in coverage-combine.

Made-with: Cursor
Use an existing top-level endpoint callable for legacy get_request_handler path coverage so coverage-combine can reach 100%.

Made-with: Cursor
@rajratangm
Copy link
Copy Markdown
Author

Could a maintainer please add the label to this PR? The required label check expects one of: breaking, security, feature, bug, refactor, upgrade, docs, lang-all, internal. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant