<p dir="auto">Greetings and congrats again for this amazingly well documented library, I'm happy Twitter made me discover this !</p>
<p dir="auto">So I decided to dive a little bit into it, and I was in particular interested in the Starlette DatabaseMiddleware.</p>
<p dir="auto">I then cloned the related <a href="https://github.com/encode/starlette/blob/master/tests/test_database.py">test</a> in Starlette and reworked it using FastAPI here: <a href="https://github.com/euri10/fastapi/blob/dbmiddleware/tests/test_dbmiddleware.py">https://github.com/euri10/fastapi/blob/dbmiddleware/tests/test_dbmiddleware.py</a></p>
<p dir="auto">so in this test we got:</p>
<ul dir="auto">
<li>
<p dir="auto">one starlette instance of Starlette <a href="https://github.com/euri10/fastapi/blob/7b42e4d25383e33dcb4445aa657a2e5e3d9cb855/tests/test_dbmiddleware.py#L35"><code class="notranslate">starlette=Starlette()</code></a> that makes the very same tests as in the test_database mentionned aboveand</p>
</li>
<li>
<p dir="auto">one fastapi instance of FastAPI <a href="https://github.com/euri10/fastapi/blob/7b42e4d25383e33dcb4445aa657a2e5e3d9cb855/tests/test_dbmiddleware.py#L40"><code class="notranslate">fastapi=FastAPI()</code></a>, whose routes have been adapted by me to take the new "framework" into account (mainly switching to app.get and app.post instead of app.route, making use of pydantic models etc,....)</p>
</li>
</ul>
<p dir="auto">Each instance is tested separately in a class, namely <a href="https://github.com/euri10/fastapi/blob/7b42e4d25383e33dcb4445aa657a2e5e3d9cb855/tests/test_dbmiddleware.py#L192">class TestStarletteStyle():</a> and <a href="https://github.com/euri10/fastapi/blob/7b42e4d25383e33dcb4445aa657a2e5e3d9cb855/tests/test_dbmiddleware.py#L270">class TestFastAPIStyle():</a></p>
<p dir="auto">Obviously TestStarletteStyle passes like in the original file.<br>
Interestingly if you change <code class="notranslate">starlette=Starlette()</code> to <code class="notranslate">starlette=FastAPI()</code> TestStarletteStyle passes also, which makes sense since if I got it correctly a <code class="notranslate">fastapi.post</code> is the same as a <code class="notranslate">fastapi.route, methods=["POST"]</code></p>
<p dir="auto">However <code class="notranslate">TestFastAPIStyle</code> fails at various points, all tests fails but not all asserts:</p>
<ul dir="auto">
<li>fails <a href="https://github.com/euri10/fastapi/blob/7b42e4d25383e33dcb4445aa657a2e5e3d9cb855/tests/test_dbmiddleware.py#L293-L295">here</a> as while the previous RuntimeError has been raised, the entry has been put in the database, while in the TestStarletteStyle the RuntimeError prevented this, is seems related to the rollback_on_shutdown=True that would not have been taken into account if i understand correctly, but take this with caution I'm brand new to your code and starlette's one.</li>
<li>fails <a href="https://github.com/euri10/fastapi/blob/7b42e4d25383e33dcb4445aa657a2e5e3d9cb855/tests/test_dbmiddleware.py#L317-L319">here</a> too, and looking at what we got in db (5 entries instead of 2 in the test) it seems also related to a rollback not made.</li>
<li>finally fails <a href="https://github.com/euri10/fastapi/blob/7b42e4d25383e33dcb4445aa657a2e5e3d9cb855/tests/test_dbmiddleware.py#L335">here</a> too, and we got 6 entries in db instead of 1 tested, same intuition.</li>
</ul>
<p dir="auto">So there's seem to be something incorrect with the rollback setting, happy to dig further but you surely have ideas, if making a PR with my failing branch is ok let me know</p>
<h3 dir="auto">First check</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I added a very descriptive title to this issue.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I used the GitHub search to find a similar issue and didn't find it.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I searched the FastAPI documentation, with the integrated search.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already searched in Google "How to X in FastAPI" and didn't find any information.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already read and followed all the tutorial in the docs and didn't find an answer.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/samuelcolvin/pydantic">Pydantic</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/swagger-api/swagger-ui">Swagger UI</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/Redocly/redoc">ReDoc</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> After submitting this, I commit to one of:
<ul dir="auto">
<li>Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.</li>
<li>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.</li>
<li>Implement a Pull Request for a confirmed bug.</li>
</ul>
</li>
</ul>

<h3 dir="auto">Example</h3>
<p dir="auto">Here's a self-contained, <a href="https://stackoverflow.com/help/minimal-reproducible-example" rel="nofollow">minimal, reproducible, example</a> with my use case:</p>

<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from typing import List, Optional

from fastapi import FastAPI, Header

app = FastAPI()


@app.get(&quot;/items/&quot;)
async def read_items(x_token: Optional[List[str]] = Header(None)):

    return {&quot;X-Token values&quot;: x_token}"><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">List</span>, <span class="pl-v">Optional</span>

<span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">FastAPI</span>, <span class="pl-v">Header</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>()


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">get</span>(<span class="pl-s">"/items/"</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">read_items</span>(<span class="pl-s1">x_token</span>: <span class="pl-v">Optional</span>[<span class="pl-v">List</span>[<span class="pl-s1">str</span>]] <span class="pl-c1">=</span> <span class="pl-v">Header</span>(<span class="pl-c1">None</span>)):

    <span class="pl-k">return</span> {<span class="pl-s">"X-Token values"</span>: <span class="pl-s1">x_token</span>}</pre></div>
<h3 dir="auto">Description</h3>

<ul dir="auto">
<li>What I did with HTTPie(and same as what Swagger did with curl):</li>
</ul>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$ http -v :8000/items/ X-Token:first,second
GET /items/ HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8000
User-Agent: HTTPie/2.3.0
X-Token: first,second"><pre class="notranslate">$ http -v :8000/items/ X-Token:first,second
GET /items/ HTTP/1.1
Accept: <span class="pl-k">*</span>/<span class="pl-k">*</span>
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8000
User-Agent: HTTPie/2.3.0
X-Token: first,second</pre></div>
<ul dir="auto">
<li>It returns a JSON with</li>
</ul>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
    &quot;X-Token values&quot;: [
        &quot;first,second&quot;
    ]
}"><pre class="notranslate">{
    <span class="pl-ent">"X-Token values"</span>: [
        <span class="pl-s"><span class="pl-pds">"</span>first,second<span class="pl-pds">"</span></span>
    ]
}</pre></div>
<ul dir="auto">
<li>But I expected it to return:</li>
</ul>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
    &quot;X-Token values&quot;: [
        &quot;first&quot;,
        &quot;second&quot;
    ]
}"><pre class="notranslate">{
    <span class="pl-ent">"X-Token values"</span>: [
        <span class="pl-s"><span class="pl-pds">"</span>first<span class="pl-pds">"</span></span>,
        <span class="pl-s"><span class="pl-pds">"</span>second<span class="pl-pds">"</span></span>
    ]
}</pre></div>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>OS: macOS 11.2.3</li>
<li>FastAPI Version: 0.63.0</li>
<li>Python version: 3.9.4</li>
</ul>
<h3 dir="auto">Additional context</h3>
<p dir="auto">From <a href="https://fastapi.tiangolo.com/tutorial/header-params/#duplicate-headers" rel="nofollow">Header Parameters docs</a>, it said FastAPI can receive multiple values for a single header. However, It's not working properly. Thus, I had to pop it and split it with <code class="notranslate">,</code>.</p>
<p dir="auto">It's not a big deal, but I think the official doc must have reliability. Frankly, I'm confused this is a bug or a feature...</p>