FastAPI ondersteunt zowel async def als regular def voor path operations. De keuze is belangrijk voor prestaties: gebruik async def als je non-blocking I/O kunt , en regular als je code blocking (synchrone) bewerkingen aanroept.
FastAPI ondersteunt zowel async def als regular def voor path operations. De keuze is belangrijk voor prestaties: gebruik async def als je non-blocking I/O kunt , en regular als je code blocking (synchrone) bewerkingen aanroept.
awaitdef@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
De kritieke regel: zet nooit blocking calls in async def — het blokkeert de event loop en vernietigt gelijktijdigheid. Gebruik ofwel een async library met await, ofwel een plain def (wat FastAPI veilig in een thread pool uitvoert).
De juiste keuze tussen async def en def beïnvloedt rechtstreeks de prestaties en concurrency van je API, en het verkeerd doen is een veelvoorkomende, ernstige fout.
De kerngedachte is dat async def alleen voordelig is als je non-blocking bewerkingen await — een blocking call (zoals de synchrone requests library of een blocking database driver) in een async def zet, blokkeert de hele event loop, bevriest alle gelijktijdige verzoeken en vernietigt het doel van async.
Omgekeerd voert FastAPI slim plain def endpoints uit in een thread pool, dus synchrone/blocking code is daar veilig.
Deze regel begrijpen — async def gebruiken met echt async libraries, plain def gebruiken voor blocking code, en nooit blocking calls mixen in async def — is essentieel voor het schrijven van performante FastAPI endpoints en het vermijden van de subtiele maar verwoestende fout van het per ongeluk serialiseren van alle verzoeken achter een geblokkeerde event loop.