FastAPI รองรับทั้ง async def และ def ทั่วไปสำหรับการดำเนินการพาธ การเลือกมีความสำคัญต่อประสิทธิภาพ: ใช้ async def เมื่อคุณสามารถ await I/O ที่ไม่ปิดกั้น และ ทั่วไปเมื่อโค้ดของคุณเรียกการดำเนินการที่ปิดกั้น (ซิงโครนัส)
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
กฎที่สำคัญ: อย่าใส่การเรียกที่ปิดกั้นใน async def — มันจะปิดกั้น event loop และทำลายความพร้อมกัน ใช้ไลบรารี่ async ที่มี await หรือใช้ def ทั่วไป (ซึ่ง FastAPI จะรันอย่างปลอดภัยในพูลของเธรด)
การเลือกให้ถูกต้องระหว่าง async def และ def มีผลโดยตรงต่อประสิทธิภาพและความพร้อมกันของ API ของคุณ และการทำให้ผิด เป็นข้อผิดพลาดที่ธรรมชาติและร้ายแรง
ข้อมูลเชิงลึกหลักคือ async def มีประโยชน์เฉพาะเมื่อคุณ await การดำเนินการที่ไม่ปิดกั้น — การใส่การเรียกที่ปิดกั้น (เช่น ไลบรารี่ requests ที่ซิงโครนัส หรือไดรเวอร์ฐานข้อมูลที่ปิดกั้น) ใน async def จะปิดกั้น event loop ทั้งหมด ทำให้ทุกคำขอพร้อมกันเป็นการแข็งตัว และทำลายวัตถุประสงค์ของ async
ในทางกลับกัน FastAPI จะรัน def endpoints ทั่วไปในพูลของเธรดอย่างฉลาด ดังนั้นโค้ดซิงโครนัส/ปิดกั้นจึงปลอดภัยที่นั่น
การทำความเข้าใจกฎนี้ — ใช้ async def กับไลบรารี่ที่ async จริงๆ ใช้ def ทั่วไปสำหรับโค้ดที่ปิดกั้น และอย่าผสมการเรียกที่ปิดกั้นใน async def — เป็นสิ่งจำเป็นในการเขียน FastAPI endpoints ที่มีประสิทธิภาพ และหลีกเลี่ยงข้อผิดพลาดที่ลึกซึ้งแต่ร้ายแรงของการทำให้คำขอทั้งหมดเป็นซีเรียลไม่สมควร ที่อยู่เบื้องหลัง event loop ที่ปิดกั้น