FastAPI suportă atât async def cât și def obișnuit pentru operații de cale. Alegerea este importantă pentru performanță: folosește async def când poți I/O non-blocare, și obișnuit când codul tău apelează operații blocare (sincrone).
FastAPI suportă atât async def cât și def obișnuit pentru operații de cale. Alegerea este importantă pentru performanță: folosește async def când poți I/O non-blocare, și obișnuit când codul tău apelează operații blocare (sincrone).
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
Regula critică: nu pune niciodată apeluri blocante în async def — blochează event loop-ul și distruge concurența. Fie folosești o bibliotecă async cu await, fie folosești un def simplu (pe care FastAPI îl execută cu siguranță într-un thread pool).
A alege corect între async def și def afectează direct performanța și concurența API-ului tău, și a face greșeala este o eroare comună și gravă.
Insightul-cheie este că async def este benefic doar când awaiti operații non-blocante — a pune un apel blocant (cum ar fi biblioteca sincronă requests sau un driver de bază de date blocant) în interiorul unui async def blochează întregul event loop, îngheață toate cererile concurente și distruge scopul async.
Invers, FastAPI execută inteligent endpoint-urile def simple într-un thread pool, deci codul sincron/blocant este sigur acolo.
A înțelege această regulă — folosește async def cu biblioteci cu adevărat async, folosește def simplu pentru cod blocant, și nu amesteca niciodată apeluri blocante în async def — este esențial pentru a scrie endpoint-uri FastAPI performante și pentru a evita eroarea subtilă dar devastatoare de a serializa accidental toate cererile în spatele unui event loop blocat.