Breaking Changes
Unblocks ✨ SO MANY THINGS ✨
Before this, router.include_router(other_router) would take each path operation from other_router and "clone" it, or recreate it from scratch.
This would mean that in the end there was only one top level router, part of the app.
The way it is structured here is that there are a few additional classes to handle intermediate metadata for router and route inclusion. That way the information of "router X includes Y and Y includes Z" is stored somewhere, without affecting (recreating / clonning) the final route.
Non Objectives
Dependencies for 404: previously I intended to support dependencies that would be executed even for 404, but that would conflict with the fact that a router could not find a match, but the next router did find a match. Executing dependencies in the router that did not find a match would not make sense, they could consume the request, body, etc. This original idea was discarded.
Specific Breaking Changes
Now router.routes is no longer a plain list of APIRoute objects, it can contain these intermediate objects that can contain additional routers, forming a tree.
Any logic that depended on iterating on the router.routes directly would be affected, that logic cannot expect to be able to extract data from a plain list of routes, as it's no longer a plain list but a tree.
Additionally, any logic that iterated on router.routes to modify them would now also see these new objects, and would not see all the routes in the app.
router.routes should be considered an internal implementation detail, only passed around to the FastAPI functions that need it.
Features
- Adding routes (path operations) after a router is included now works, they are reflected as they are not copied.
- Including
subrouterinmainroutercan be done before adding routes (path operations) tosubrouter, because now the the entire object is stored instead of copying the routes. - As routes are not copied, in some cases that might save some memory.
Alpha Features
This is not documented yet, so it's not officially supported yet and could change in the future.
But, as APIRoute and APIRouter instances are now preserved, they could be customized.
APIRouter has two new methods, .matches() and .handle(), counterpart to the existing ones in APIRoute. With this a router could customize how it matches and handles requests. For example, it could match only requests that include some specific header, for example for handling versions in headers.
Still, for now, consider this very experimental and potentially changing and breaking in the future.
Future Features Enabled
- Custom
APIRoutesubclasses (undocumented, but alraedy works as desccribed above) - Custom
APIRoutersubclasses (undocumented, but already works as described above) - Dependencies per router
- Exception handlers per router
- Middleware per router
- Other features planned
Docs
- 📝 Update release notes. PR #15747 by @tiangolo.
- 📝 Update FastAPI Cloud deployment instructions. PR #15724 by @alejsdev.
- ✏️ Use
Annotatedin inline example indocs/en/docs/tutorial/body-multiple-params.md. PR #15591 by @TheArchons. - 📝 Remove "NGINX Unit" from the list of ASGI-servers in docs. PR #15475 by @angryfoxx.
- 📝 Update
docs/en/docs/tutorial/security/oauth2-jwt.md. PR #14781 by @zadevhub.
Translations
- 🌐 Update translations for zh-hant (update-outdated). PR #15671 by @tiangolo.
- 🌐 Update translations for es (update-outdated). PR #15670 by @tiangolo.
- 🌐 Update translations for fr (update-outdated). PR #15669 by @tiangolo.
- 🌐 Update translations for ja (update-outdated). PR #15668 by @tiangolo.
- 🌐 Update translations for pt (update-outdated). PR #15667 by @tiangolo.
- 🌐 Update translations for tr (update-outdated). PR #15666 by @tiangolo.
- 🌐 Update translations for zh (update-outdated). PR #15665 by @tiangolo.
- 🌐 Update translations for ko (update-outdated). PR #15664 by @tiangolo.
- 🌐 Update translations for de (update-outdated). PR #15673 by @tiangolo.
- 🌐 Update translations for uk (update-outdated). PR #15672 by @tiangolo.
- 🌐 Update translations for ru (update-outdated). PR #15674 by @tiangolo.
Internal
- 🔧 Update sponsors: remove TalorData. PR #15744 by @tiangolo.
- 🔧 Update sponsors: remove ExoFlare. PR #15736 by @tiangolo.
- 🔧 Update sponsors: remove InterviewPal. PR #15735 by @tiangolo.
- 🔧 Update sponsors: remove Liblab. PR #15731 by @tiangolo.
- 🔧 Update sponsors: remove Scalar. PR #15730 by @tiangolo.
- ⬆ Bump the python-packages group across 1 directory with 6 updates. PR #15721 by @dependabot[bot].
- ⬆ Bump python-multipart from 0.0.29 to 0.0.30. PR #15723 by @dependabot[bot].
- ⬆ Bump the github-actions group with 3 updates. PR #15720 by @dependabot[bot].
- ⬆ Bump starlette from 1.1.0 to 1.2.1. PR #15722 by @dependabot[bot].
- ⬆ Bump https://github.com/crate-ci/typos from v1.46.0 to v1.47.1 in the pre-commit group. PR #15719 by @dependabot[bot].
- 🔧 Update sponsors, add Rapidproxy. PR #15689 by @tiangolo.
- 🔧 Update sponsors: Remove TestMu. PR #15688 by @tiangolo.
- ⬆ Bump the python-packages group across 1 directory with 11 updates. PR #15683 by @dependabot[bot].
- ⬆ Bump aiohttp from 3.13.4 to 3.14.0. PR #15681 by @dependabot[bot].
- ⬆ Bump the github-actions group with 2 updates. PR #15682 by @dependabot[bot].
- ⬆ Bump starlette from 1.0.0 to 1.1.0. PR #15684 by @dependabot[bot].
- 👥 Update FastAPI People - Experts. PR #15677 by @tiangolo.
- 👥 Update FastAPI GitHub topic repositories. PR #15675 by @tiangolo.
- 👥 Update FastAPI People - Contributors and Translators. PR #15662 by @tiangolo.
- 👷 Automate release preparation. PR #15661 by @tiangolo.
- 🔥 Remove slim package stub, deprecated for a while. PR #15649 by @tiangolo.
- ⬆ Bump authlib from 1.6.11 to 1.7.2. PR #15512 by @dependabot[bot].
- ⬆ Bump pymdown-extensions from 10.21.2 to 10.21.3. PR #15569 by @dependabot[bot].
- ⬆ Bump CodSpeedHQ/action from 4.14.0 to 4.15.1. PR #15513 by @dependabot[bot].
- ⬆ Bump python-multipart from 0.0.26 to 0.0.29. PR #15595 by @dependabot[bot].
- 🔒️ Improve GitHub actions security. PR #15607 by @YuriiMotov.
- ⚰️ Remove ruff and coverage ignores for non-existing files. PR #15610 by @YuriiMotov.
- ✅ Use custom
changing_dirinstead ofCLIRunner.isolated_filesystemto set working dir. PR #15616 by @YuriiMotov. - ✅ Add
httpx2test dependency to avoid deprecation warning. PR #15603 by @YuriiMotov. - ⬆ Bump the python-packages group with 15 updates. PR #15594 by @dependabot[bot].
- 👷 Configure Dependabot to group updates and update weekly. PR #15560 by @YuriiMotov.