FastAPI stöder både async def och vanlig def för vägar. Valet är viktigt för prestanda: använd async def när du kan await icke-blockande I/O, och vanlig när din kod anropar blockande (synkrona) operationer.
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
Den kritiska regeln: lägg aldrig blockande anrop i async def — det blockerar event loop och förstör samtidighet. Använd antingen ett async-bibliotek med await, eller använd en vanlig def (som FastAPI säkert kör i en thread pool).
Att välja rätt mellan async def och def påverkar direkt din API:s prestanda och samtidighet, och att göra fel är ett vanligt, allvarligt misstag.
Insikten är att async def bara är fördelaktig när du await icke-blockande operationer — att placera ett blockande anrop (som det synkrona requests-biblioteket eller en blockande databasdrivrutin) i async def blockerar hela event loop, fryser alla konkurrerande begäranden och förstör syftet med async.
Omvänt kör FastAPI smart vanlig def endpoints i en thread pool, så synkron/blockande kod är säker där.
Att förstå denna regel — använd async def med verkligen async-bibliotek, använd vanlig def för blockande kod, och blanda aldrig blockande anrop i async def — är väsentligt för att skriva högpresterande FastAPI-endpoints och undvika det subtila men förödande misstaget att oavsiktligt serialisera alla begäranden bakom en blockerad event loop.