FastAPI podporuje jak async def tak běžný def pro path operations. Volba je důležitá pro výkon: používejte async def když můžete await neblokující I/O operace, a běžný když váš kód volá blokující (synchronní) operace.
def@app.get("/async")
async def async_endpoint():
data = await fetch_from_api() # await non-blocking I/O — efficient
return data
@app.get("/sync")
def sync_endpoint():
data = blocking_db_call() # ordinary blocking code
return data
async def → runs on the main event loop. Efficient ONLY if you await non-blocking calls.
⚠️ A BLOCKING call inside async def blocks the WHOLE event loop → kills concurrency!
def → FastAPI runs it in a THREAD POOL, so blocking code doesn't block the event loop.
Safe for synchronous/blocking libraries.
# ✅ async def — when you can await async libraries (httpx, async DB drivers)
async def get_user():
async with httpx.AsyncClient() as c:
return await c.get(url)
# ✅ plain def — when using SYNCHRONOUS/blocking libraries (requests, sync ORM)
def get_user():
return requests.get(url).json() # blocking → FastAPI runs it in a thread
# ❌ THE DANGEROUS MISTAKE — blocking call inside async def
async def bad():
return requests.get(url).json() # blocks the event loop! Use `def` or an async client
Kritické pravidlo: nikdy nevkládejte blokující volání do async def — blokuje event loop a zničí souběžnost. Buď používejte async knihovnu s await, nebo použijte běžný def (který FastAPI bezpečně spouští v thread poolu).
Správná volba mezi async def a def přímo ovlivňuje výkon a souběžnost vaší API, a chyba je běžnou a vážnou chybou.
Klíčová myšlenka je, že async def je prospěšný pouze když await neblokující operace — vložení blokujícího volání (jako synchronní knihovna requests nebo blokující databázový ovladač) do async def blokuje celý event loop, zamrazí všechny souběžné požadavky a anuluje účel asyncu.
Opačně FastAPI chytře spouští běžné def endpointy v thread poolu, takže synchronní/blokující kód je tam bezpečný.
Pochopení tohoto pravidla — používejte async def se skutečně async knihovnami, používejte běžný def pro blokující kód, a nikdy nemíchejte blokující volání do async def — je nezbytné pro psaní výkonných FastAPI endpointů a pro vyhnutí se jemné, ale ničivé chybě nechtěného serializování všech požadavků za blokovaným event loopem.