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

First check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.
  • After submitting this, I commit to:
    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
    • Or, I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
    • Implement a Pull Request for a confirmed bug.

Example

Here's a self-contained minimal, reproducible, example with my use case:

from fastapi import FastAPI
import pytest
from fastapi.testclient import TestClient

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

client = TestClient(app)

def test_index_head():
    response = client.head("/")
    assert response.status_code == 200

Description

  • The above test fails because the HEAD request returns a 405.
  • This is counterintuitive.

The solution you would like

  • To better support the HTTP standard, all routes that handle GET methods should automatically handle HEAD methods, too.
  • This is similar to what Starlette's router already does: Better support for HEAD method Kludex/starlette#45
  • This should happen without requiring the developer to do any additional work.

Describe alternatives you've considered

  • It's currently possible to do this manually by adding @app.head and a helper method for each route, but it's cumbersome:
@app.head("/")
def read_root_head():
    return Response()
  • It could also be done using middleware, but that would incur a performance overhead.

Environment

  • OS: [e.g. Linux / Windows / macOS]: Linux
  • FastAPI Version [e.g. 0.3.0]: 0.60.1
  • Python version: 3.8.5