Repository navigation
Improvement plan #3
Copy link
Copy link
Open
Description
A review of the router against FastAPI 0.142.2 and 0.143.3, with each behavior finding
compared against a plain FastAPI route with Pydantic models, found the issues below. They are
grouped into steps; each step will be a separate pull request.
1. Request handling and CI (done in #4, released in 0.0.2)
- A JSON body without a
Content-Typeheader is accepted even with FastAPI's default
strict_content_type=True. FastAPI rejects it, because such a request can be sent
cross-origin without a CORS preflight. - Deeply nested JSON in a body returns 500 (
RecursionError) instead of 400. - A NaN or infinite float in a typed response can return 500; Pydantic encodes it as
null. - A body that does not match its schema returns 422 before dependencies run, so an
unauthenticated request with such a body gets 422 instead of the 401 from an
authentication dependency. -
-> Noneis treated as a typednullresponse, sostatus_code=204is rejected at
registration and the OpenAPI schema is{"type": "null"}. -
Form()parameters andFile()parameters of typebytesare rejected at
registration. - There is no CI for pushes and pull requests; tests run only when a release is
tagged.
2. OpenAPI document
- An Enum used both in a parameter and inside a Struct makes
/openapi.jsonreturn
500 (Conflicting OpenAPI component). - Enum parameter schemas reference
#/$defs/..., which does not exist in the
document. - Two Structs with the same name from different modules conflict.
-
install_openapidepends on the routers passed to it: a router that is not passed,
a route added to a router after it was included, or a plainAPIRouterleaves dangling
references or fails. Webhooks and callbacks are not covered, and components of routes
withinclude_in_schema=Falseare still added. Routes could be discovered from the
application when the document is built, with the router arguments kept for
compatibility. -
Body(description=..., examples=...), arequestBodyinopenapi_extraand
response examples are overwritten. - A Struct or list parameter with the same name as a path parameter becomes a request
body instead of failing at registration, and the document is invalid. - The 415 response is not documented.
3. Request and response handling
-
pattern=on parameters is checked with Pythonre(unanchored search), so a
trailing newline passes^...$and a backtracking pattern can block the event loop;
Pydantic uses a linear-time engine.Body(pattern=...)andField(pattern=...)inside
containers are affected too. - Generator endpoints (JSON Lines and server-sent events) return 500 or fail at
registration. - Untyped returns of values msgspec cannot encode (
Path, IP addresses,HttpUrl,
SecretStr, other objects) return 500; FastAPI falls back tojsonable_encoder. - The error for an integer parameter over the digit limit mentions
sys.set_int_max_str_digits(). - Body validation errors have
loc["body"]and only the first error; the path appears
only inside the message text. - A typed return with a custom
response_classis rejected at registration.
4. Packaging and typing
- No
py.typed, so type checkers treat the package as untyped. -
MsgspecRouteis not exported, althoughroute_classmust extend it. - The sdist includes untracked local files; set an explicit include list.
- Lint configuration, Dependabot for GitHub Actions, classifiers and a declared
pydanticdependency. - Tests for sync endpoints,
Body(embed=True), empty bodies and list query
parameters.
5. Performance (not planned)
- On routes with several query parameters, most of the parameter handling time is
spent in FastAPI's generic extraction (request_params_to_args). A per-route extractor
built at registration removed about 30 to 40 µs per request on a route with seven query
parameters in a local in-process measurement. On the service from the README
benchmarks that is an estimated 3 to 5% of the API CPU time per response, and the
extractor would depend on more private FastAPI code, so this item is not planned.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
Fix request handling issues and add CI