<p dir="auto">Hey <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/tiangolo/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/tiangolo">@tiangolo</a>! I've been wondering why FastAPI doesn't use the function's return <code class="notranslate">-&gt;</code> signature instead of the <code class="notranslate">response_model</code> argument? I think it would be a bit more natural to express the return schema like this:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@router.post(&quot;/&quot;)
def create_worker(
    params: CreateWorker, auth_token: str = Depends(shared.get_authorization)
) -&gt; CreateWorkerResponse:
    # code
    return CreateWorkerResponse(...)"><pre class="notranslate"><span class="pl-en">@<span class="pl-s1">router</span>.<span class="pl-en">post</span>(<span class="pl-s">"/"</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">create_worker</span>(
    <span class="pl-s1">params</span>: <span class="pl-v">CreateWorker</span>, <span class="pl-s1">auth_token</span>: <span class="pl-s1">str</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">shared</span>.<span class="pl-s1">get_authorization</span>)
) <span class="pl-c1">-&gt;</span> <span class="pl-v">CreateWorkerResponse</span>:
    <span class="pl-c"># code</span>
    <span class="pl-k">return</span> <span class="pl-v">CreateWorkerResponse</span>(...)</pre></div>
<p dir="auto"><strong>Is your feature request related to a problem? Please describe.</strong><br>
Primarily for the sake of the generated OpenAPI spec (but also for security/validation reasons), I currently specify a <code class="notranslate">response_model</code> for nearly all of my endpoints, but for the vast majority of my endpoints, the <code class="notranslate">response_model</code> is the same as the type that the endpoint returns.</p>
<p dir="auto">This means that I am frequently duplicating the <code class="notranslate">response_model</code> in the return annotation.</p>
<p dir="auto">In order to reduce duplication/room for copying/refactoring mistakes, it would be great if it were possible to (optionally) infer the <code class="notranslate">response_model</code> from the endpoint signature.</p>
<p dir="auto">It should still be possible to override the value, and it should be ignored if a raw <code class="notranslate">Response</code> class is returned, I would just want the <em>default</em> to be the annotated return type of the endpoint. <strong>Note: this implementation would also make it much easier to catch anywhere the <code class="notranslate">response_model</code> <em>differed</em> from the returned value's type while scanning through code.</strong></p>
<p dir="auto">To be clear, I <em>don't</em> think this needs to be the default behavior, I just would like the option to enable it.</p>
<hr>
<p dir="auto">I am currently using the following subclass of <code class="notranslate">APIRouter</code> in my code to enable this:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from typing import TYPE_CHECKING, Any, Callable, get_type_hints

from fastapi import APIRouter


class InferringRouter(APIRouter):
    if not TYPE_CHECKING:

        def add_api_route(self, path: str, endpoint: Callable[..., Any], **kwargs: Any) -&gt; None:
            if kwargs.get(&quot;response_model&quot;) is None:
                kwargs[&quot;response_model&quot;] = get_type_hints(endpoint).get(&quot;return&quot;)
            return super().add_api_route(path, endpoint, **kwargs)

    else:  # pragma: no cover
        pass"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">typing</span> <span class="pl-k">import</span> <span class="pl-v">TYPE_CHECKING</span>, <span class="pl-v">Any</span>, <span class="pl-v">Callable</span>, <span class="pl-s1">get_type_hints</span>

<span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">APIRouter</span>


<span class="pl-k">class</span> <span class="pl-v">InferringRouter</span>(<span class="pl-v">APIRouter</span>):
    <span class="pl-k">if</span> <span class="pl-c1">not</span> <span class="pl-v">TYPE_CHECKING</span>:

        <span class="pl-k">def</span> <span class="pl-en">add_api_route</span>(<span class="pl-s1">self</span>, <span class="pl-s1">path</span>: <span class="pl-s1">str</span>, <span class="pl-s1">endpoint</span>: <span class="pl-v">Callable</span>[..., <span class="pl-v">Any</span>], <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>: <span class="pl-v">Any</span>) <span class="pl-c1">-&gt;</span> <span class="pl-c1">None</span>:
            <span class="pl-k">if</span> <span class="pl-s1">kwargs</span>.<span class="pl-en">get</span>(<span class="pl-s">"response_model"</span>) <span class="pl-c1">is</span> <span class="pl-c1">None</span>:
                <span class="pl-s1">kwargs</span>[<span class="pl-s">"response_model"</span>] <span class="pl-c1">=</span> <span class="pl-en">get_type_hints</span>(<span class="pl-s1">endpoint</span>).<span class="pl-en">get</span>(<span class="pl-s">"return"</span>)
            <span class="pl-k">return</span> <span class="pl-en">super</span>().<span class="pl-en">add_api_route</span>(<span class="pl-s1">path</span>, <span class="pl-s1">endpoint</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>)

    <span class="pl-k">else</span>:  <span class="pl-c"># pragma: no cover</span>
        <span class="pl-k">pass</span></pre></div>
<p dir="auto">I think it would be nice if this capability was upstreamed though, both to ensure it is maintained, but also so others can benefit.</p>
<hr>
<p dir="auto"><strong>Describe the solution you'd like</strong></p>
<p dir="auto">Rather than using the above implementation (which has some problems -- for example, it isn't possible to specify <code class="notranslate">None</code> as the <code class="notranslate">response_model</code> with an annotated return type), I think it would be better if there were a boolean-valued keyword argument to the <code class="notranslate">APIRouter</code> initializer that, if enabled, would cause the default behavior to be to have the annotated return type used as the <code class="notranslate">response_model</code> by default.</p>