Skip to content

Automatically support HEAD method for all GET routes#15356

Open
Herrtian wants to merge 1 commit intofastapi:masterfrom
Herrtian:feature/auto-head-for-get-routes
Open

Automatically support HEAD method for all GET routes#15356
Herrtian wants to merge 1 commit intofastapi:masterfrom
Herrtian:feature/auto-head-for-get-routes

Conversation

@Herrtian
Copy link
Copy Markdown

@Herrtian Herrtian commented Apr 15, 2026

Closes #1773

GET routes now respond to HEAD requests automatically, matching what Starlette does (RFC 7231 §4.3.2).

HEAD is not added to self.methods, so it won't show up in the OpenAPI schema. Instead, APIRoute.matches() promotes HEAD→GET at routing time, and handle() lets it through.

If you explicitly define a @app.head() route, it still works and appears in the schema as before.

Includes 10 new tests covering the various cases (path params, response models, routers, explicit HEAD, etc). Updated one existing test that relied on the old 405 behavior.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 15, 2026

Merging this PR will not alter performance

✅ 20 untouched benchmarks


Comparing Herrtian:feature/auto-head-for-get-routes (fb78a21) with master (6f9a102)1

Open in CodSpeed

Footnotes

  1. No successful run was found on master (9653034) during the generation of this report, so 6f9a102 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

RFC 7231 §4.3.2 states that the server SHOULD send the same header fields
in response to a HEAD request as it would have sent for GET. Starlette
does this by default but FastAPI's APIRoute did not.

This adds automatic HEAD support by overriding matches() and handle() on
APIRoute to accept HEAD requests when the route has GET in its methods.

Key design decisions:
- HEAD is NOT added to self.methods, so it stays out of the OpenAPI schema
- Explicit HEAD routes still work and appear in OpenAPI when declared
- The match promotion only happens when HEAD is not already in methods,
  so explicit @app.head() or methods=["GET","HEAD"] are unaffected
- POST/PUT/DELETE/PATCH routes are not affected

Closes fastapi#1773
@Herrtian Herrtian force-pushed the feature/auto-head-for-get-routes branch from f0b347d to fb78a21 Compare April 15, 2026 17:54
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.

Automatically support HEAD method for all GET routes, as Starlette does

1 participant