Bỏ qua điều hướng

FastAPI là gì? Framework Python xây API nhanh và tự sinh tài liệu

FastAPI là gì? Framework Python hiệu suất cao dựa trên OpenAPI, hỗ trợ async/await, tự động kiểm tra dữ liệu và sinh tài liệu Swagger/ReDoc.

Tuan Tran Van
15 phút đọc
Mục lục (10 phần)
  1. FastAPI là gì?
  2. Một endpoint FastAPI trông như thế nào?
  3. Type hint và Pydantic: kiểm tra dữ liệu và tự sinh tài liệu
  4. Bên dưới FastAPI: ASGI, Starlette và Uvicorn
  5. async def hay def: FastAPI xử lý đồng thời ra sao?
  6. Depends: dependency injection trong FastAPI
  7. Những sai lầm khiến FastAPI chạy chậm
  8. FastAPI, Flask hay Django — chọn cái nào?
  9. Nên bắt đầu với FastAPI từ đâu?
  10. Tài liệu tham khảo

FastAPI là một web framework hiện đại, hiệu suất cao để xây dựng API với Python, dựa trên type hints (chú thích kiểu dữ liệu) tiêu chuẩn của Python.

Nó tối ưu hóa đồng thời cả hiệu suất thực thi của hệ thống lẫn tốc độ viết code của lập trình viên. Framework này tận dụng các tính năng của Python 3.10 trở lên để giải quyết bài toán muôn thuở của các hệ thống cũ: sự chậm chạp của ngôn ngữ thông dịch và sự lỏng lẻo trong kiểm soát kiểu dữ liệu.

Điểm khiến FastAPI đáng chọn cho các dự án chạy trong môi trường thực tế (production) không phải là tính năng "màu mè", mà là việc nó tuân thủ chặt chẽ chuẩn OpenAPI — bộ quy ước mô tả API để máy đọc được — ngay từ lõi. Đội phát triển của chính FastAPI ước tính framework giúp tăng tốc độ viết tính năng từ 200% đến 300% và giảm khoảng 40% lỗi do lập trình viên gây ra — đây là con số từ thử nghiệm nội bộ của họ, không phải khảo sát độc lập. Việc tự động hóa khâu kiểm tra dữ liệu là thứ giúp đội ngũ kỹ sư tập trung vào logic nghiệp vụ thay vì đi bắt các lỗi vặt về định dạng request.

Về mặt hiệu suất, FastAPI cho tốc độ xử lý tương đương với Node.js hoặc Go, điều mà trước đây hiếm có framework Python nào làm được. Sự kết hợp giữa ASGI (Asynchronous Server Gateway Interface) và khả năng xử lý bất đồng bộ (async/await) cho phép hệ thống duy trì hàng ngàn kết nối cùng lúc mà không làm treo server.

Nếu bạn cần một công cụ vừa mộc về cú pháp vừa mạnh về thực thi, đây là lựa chọn hàng đầu.

Một dòng khai báo kiểu dữ liệu trong FastAPI mở ra cùng lúc ba thứ: kiểm tra dữ liệu, tài liệu API tự sinh và tốc độ xử lý cao

FastAPI là gì?

FastAPI không chỉ là một công cụ lập trình đơn lẻ mà là một hệ thống được xây dựng trên nền tảng của các tiêu chuẩn mở như OpenAPI và JSON Schema. Nó tập trung vào bốn đặc tính thực chiến: Nhanh (Fast), Dễ học (Easy), Ngắn gọn (Short) và Mạnh mẽ (Robust). Việc dựa trên các chuẩn này giúp FastAPI không chỉ làm nhiệm vụ nhận và gửi request mà còn tự động tạo ra tài liệu API tương tác, giúp việc phối hợp giữa backend và frontend trở nên mượt mà hơn.

Độ tin cậy của framework này đã được minh chứng qua các tổ chức lớn. Microsoft sử dụng FastAPI cho các dịch vụ Machine Learning (ML services) của mình để tích hợp sâu vào lõi Windows và các sản phẩm Office. Uber dùng nó để xây dựng các máy chủ REST phục vụ dự án Ludwig. Netflix và Cisco cũng đưa FastAPI vào hệ thống điều phối quản lý khủng hoảng hoặc chiến lược phát triển API-first, nhờ khả năng mở rộng (scalability) của nó.

Điểm đáng giá nhất là FastAPI không bắt bạn học một cú pháp hoàn toàn mới. Mọi thứ đều dựa trên Python type hints tiêu chuẩn. Nghĩa là bạn đang viết code Python thuần túy nhưng nhận được sức mạnh của một hệ thống có kiểu dữ liệu tĩnh (static-like typing). Chính sự tường minh này giúp mã nguồn sạch sẽ, dễ bảo trì và sẵn sàng cho môi trường thực tế.

Một endpoint FastAPI trông như thế nào?

Cấu trúc của một endpoint trong FastAPI rất trực diện. Bạn khởi tạo ứng dụng, sau đó dùng các decorator (bộ trang trí — cú pháp @ gắn thêm hành vi cho một hàm) tương ứng với các verb HTTP như @app.get hoặc @app.post để định nghĩa logic. Mỗi hàm xử lý (handler function) sẽ nhận các tham số được khai báo kiểu dữ liệu rõ ràng, và framework sẽ tự động tách biệt tham số trong đường dẫn (Path Parameters), tham số truy vấn (Query Parameters) hoặc phần thân request (Request Body) dựa trên khai báo đó.

Một ví dụ cơ bản về endpoint lấy thông tin sản phẩm:

python
from fastapi import FastAPI
 
app = FastAPI()
 
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

Trong đoạn mã trên, FastAPI thực hiện cơ chế tách biệt logic rất thông minh. Tham số item_id nằm trong đường dẫn URL nên được hiểu là Path Parameter, còn q không xuất hiện trong đường dẫn nên mặc định là Query Parameter. Nếu bạn cố tình truyền một chuỗi ký tự vào item_id (vốn yêu cầu kiểu int), framework sẽ lập tức trả về lỗi 422 Unprocessable Entity kèm mô tả chi tiết lỗi nằm ở đâu.

Cơ chế tự động trả về lỗi 422 này thuộc đúng nhóm việc mà FastAPI tự động hóa để giảm lỗi do lập trình viên gây ra. Thay vì bạn phải viết hàng chục dòng code if/else để kiểm tra dữ liệu đầu vào có phải là số hay không, FastAPI đã làm điều đó trước khi hàm của bạn chạy. Điều này đảm bảo logic bên trong hàm luôn nhận được dữ liệu sạch và đúng kiểu, giúp giảm thiểu các lỗi crash server bất ngờ trong quá trình vận hành.

Type hint và Pydantic: kiểm tra dữ liệu và tự sinh tài liệu

Pydantic là "động cơ" bên dưới giúp FastAPI xử lý dữ liệu. Đặc biệt, với sự ra đời của Pydantic V2 được viết lại bằng Rust, tốc độ xử lý, kiểm tra (validation) và chuyển đổi dữ liệu (serialization) đã tăng lên đáng kể. Cơ chế này tạo ra một nguồn sự thật duy nhất ("single source of truth"): bạn chỉ cần khai báo model một lần, và thông tin đó được dùng chung cho cả việc thực thi code lẫn việc sinh JSON Schema cho tài liệu.

Lợi ích thực tế nhất của việc dùng Python type hints là sự hỗ trợ từ các IDE như VS Code hay PyCharm. Khi bạn gõ code, IDE sẽ tự động gợi ý các thuộc tính (autocompletion) và cảnh báo ngay lập tức nếu bạn gõ sai tên khóa (key name). Với các kỹ sư lâu năm, việc này tiết kiệm hàng giờ ngồi debug chỉ vì một lỗi chính tả trong một nested object phức tạp.

FastAPI cung cấp sẵn hai giao diện tài liệu tự động: Swagger UI và ReDoc. Ngay sau khi bạn viết xong một endpoint, bạn có thể truy cập /docs để tương tác trực tiếp với API đó, điền dữ liệu vào form và xem kết quả trả về mà không cần dùng đến Postman. Mọi thay đổi trong model Pydantic sẽ được phản ánh tức thì trên các giao diện này, đảm bảo tài liệu luôn đi đôi với code thực tế.

Bên dưới FastAPI: ASGI, Starlette và Uvicorn

Để đạt được hiệu năng tiệm cận Node.js và Go, FastAPI đứng trên vai hai thư viện chuyên biệt: Starlette xử lý phần web và Pydantic xử lý phần dữ liệu. FastAPI đóng vai trò là một lớp phủ (sub-class của Starlette) để kết nối hai thành phần này. Starlette cung cấp các tính năng của một ASGI framework như WebSocket, Background Tasks và Startup/Shutdown events, với độ phủ test 100%.

Các lớp bên dưới FastAPI: request đi từ client qua Uvicorn, qua chuẩn ASGI, tới Starlette định tuyến, rồi tới FastAPI và Pydantic kiểm tra dữ liệu trước khi vào hàm xử lý

ASGI (Asynchronous Server Gateway Interface — chuẩn giao tiếp bất đồng bộ giữa server và ứng dụng Python) là tiêu chuẩn cho phép Python xử lý các kết nối bất đồng bộ. Khác với chuẩn WSGI cũ vốn chỉ xử lý tuần tự (synchronous), ASGI cho phép server tiếp nhận nhiều yêu cầu cùng lúc mà không cần chờ yêu cầu trước đó kết thúc hoàn toàn. Đây là lý do FastAPI xử lý được các tác vụ thời gian thực hoặc các kết nối duy trì lâu.

Để vận hành trong thực tế, bạn cần một server ASGI tốc độ cao như Uvicorn. Uvicorn được xây dựng dựa trên uvloophttptools, giúp tối ưu hóa việc truyền tải dữ liệu ở mức thấp nhất. Sự phối hợp giữa ASGI, Starlette và Uvicorn tạo ra một pipeline xử lý request rất ngắn, biến Python thành ngôn ngữ có khả năng xây dựng các hệ thống backend chịu tải cao (high-throughput).

async def hay def: FastAPI xử lý đồng thời ra sao?

Nhiều người lầm tưởng rằng dùng FastAPI thì mọi hàm đều phải là async def. Thực tế, bạn chỉ nên dùng async def cho các tác vụ hướng I/O (I/O-bound) như gọi database hay gọi API bên thứ ba. Lúc này, Python dùng cơ chế concurrency (đồng thời): trong khi chờ database trả kết quả, server sẽ tạm dừng hàm đó để đi phục vụ request của người dùng khác — giống việc bạn đi tán tỉnh crush trong lúc chờ đầu bếp làm xong burger.

So sánh hai lựa chọn: tác vụ hướng I/O dùng async def để event loop phục vụ request khác trong lúc chờ, còn tác vụ nặng CPU dùng def và được đẩy sang threadpool riêng

Ngược lại, với các tác vụ nặng CPU (CPU-bound) như xử lý ảnh hay tính toán ma trận nặng, việc dùng async def sẽ phản tác dụng vì nó chặn đứng Event Loop. Đối với các tác vụ này, bạn nên dùng def thường. Khi thấy một hàm def, FastAPI sẽ tự động đẩy hàm đó vào một threadpool riêng để chạy, giúp main thread (Event Loop) vẫn rảnh để tiếp nhận các yêu cầu mới mà không bị block.

Luồng chạy của hệ thống có thể hiểu qua hình ảnh "burger". Concurrency là khả năng bạn quản lý nhiều việc dang dở — đang đợi burger thì làm việc khác. Parallelism (song song) là khi bạn có nhiều đầu bếp (nhiều lõi CPU) làm việc cùng lúc. FastAPI cho phép bạn kết hợp cả hai: dùng async để tối ưu thời gian chờ I/O và dùng nhiều worker để tận dụng phần cứng cho các tác vụ tính toán.

Depends: dependency injection trong FastAPI

Hệ thống Dependency Injection (DI) của FastAPI cho phép bạn khai báo các "công cụ" cần thiết cho một hàm xử lý — như kết nối database hay thông tin user — một cách tường minh qua từ khóa Depends. FastAPI chịu trách nhiệm khởi tạo và "bơm" (inject) các công cụ này vào hàm của bạn, giúp code trở nên modular và giảm lặp lại logic.

Một dependency như kết nối database hay xác thực JWT được khai báo một lần rồi bơm vào nhiều endpoint, và có thể thay bằng bản giả khi chạy test

Cơ chế này hữu dụng cho các bài toán bảo mật và phân quyền. Bạn có thể tạo ra các dependency để kiểm tra JWT tokens hoặc OAuth2 scopes một lần, sau đó gắn chúng vào bất kỳ endpoint nào cần bảo vệ. Vì các dependency có thể phụ thuộc lẫn nhau, chúng tạo thành một đồ thị (dependency graph), giúp framework tự động tính toán thứ tự khởi tạo các thành phần.

Một điểm cộng lớn khác của DI là khả năng hỗ trợ testing. Trong unit test, bạn có thể dễ dàng override (ghi đè) một dependency thật bằng một bản giả (mock). Ví dụ, thay vì kết nối tới database thật gây tốn tài nguyên, bạn chỉ cần một dòng code để yêu cầu FastAPI dùng một database ảo trong bộ nhớ. Cách tiếp cận này giúp việc test hệ thống nhanh và chính xác hơn nhiều.

Những sai lầm khiến FastAPI chạy chậm

Một sai lầm sơ đẳng nhưng chết người là không cài đặt uvloophttptools trên môi trường Linux. Mặc dù FastAPI chạy được với bộ cài mặc định, thiếu hai thư viện này sẽ khiến hiệu suất giảm đáng kể — dưới tải cao, uvloop cho thông lượng gấp 2–4 lần event loop mặc định của asyncio. Lưu ý rằng uvloop không hoạt động trên Windows, nên nếu bạn phát triển trên Windows và deploy lên Linux, hãy nhớ kiểm tra lại file dependencies của mình.

Bốn cái bẫy làm FastAPI chạy chậm: thiếu uvloop, dùng JSON encoder mặc định, lạm dụng BaseHTTPMiddleware và chỉ chạy một worker trên một lõi CPU

Sai lầm thứ hai là lạm dụng BaseHTTPMiddleware. Việc dùng class này để xử lý logic middleware gây ra overhead đáng kể do cơ chế wrapping phức tạp; viết Pure ASGI middleware cho hiệu năng tốt hơn khoảng 40%. Ngoài ra, việc dùng JSON encoder mặc định của Python cũng là một nút thắt cổ chai; hãy chuyển sang dùng ORJSONResponse để tăng tốc đóng gói JSON từ 20% đến 50%.

bash
# Cài đặt các thư viện tối ưu (chỉ cho Linux/macOS)
pip install uvloop httptools orjson

Một cái bẫy tinh vi hơn nằm ở chính Pydantic: nó là công cụ tốt để kiểm tra dữ liệu ở biên của API, nhưng dùng model Pydantic cho mọi cấu trúc dữ liệu nội bộ là một sai lầm về tối ưu. Việc khởi tạo một object Pydantic chậm hơn khoảng 6,5 lần so với dataclass tiêu chuẩn của Python, và tốn bộ nhớ gấp 2,5 lần vì phải mang theo metadata phục vụ validation. Hãy giữ Pydantic ở lớp biên và dùng dataclass cho phần xử lý bên trong.

Cuối cùng, nhiều người quên tận dụng nhiều lõi CPU. Mặc định, một process Uvicorn chỉ chạy trên một lõi. Khi chạy thật, bạn cần dùng tùy chọn --workers hoặc chạy thông qua Gunicorn với UvicornWorker để tận dụng hết tài nguyên server. Với các phản hồi lớn, hãy bật GZipMiddleware để tiết kiệm băng thông, và dùng StreamingResponse thay vì nạp toàn bộ tập dữ liệu vào bộ nhớ.

FastAPI, Flask hay Django — chọn cái nào?

Việc chọn framework phụ thuộc vào yêu cầu bài toán cụ thể của bạn:

Tiêu chíDjangoFlaskFastAPI
Hiệu suấtTrung bìnhKháRất cao (async)
Hỗ trợ asyncĐã cải thiện (v5+)Hạn chếMặc định (native)
Có sẵn mọi thứCó (đầy đủ)KhôngMột phần
Tài liệu API tự độngKhôngKhôngCó (Swagger/ReDoc)
Tốc độ phát triểnNhanh (full-stack)Nhanh (prototype)Rất nhanh (API)

So sánh Django, Flask và FastAPI: Django có sẵn mọi thứ cho ứng dụng web đầy đủ, Flask tối giản và linh hoạt, FastAPI mạnh nhất cho API cần hiệu suất cao

Hãy chọn Django khi bạn cần một hệ thống "tất cả trong một", có sẵn trang quản trị (admin panel) và ORM mạnh mẽ cho các dự án phức tạp đòi hỏi sự quy chuẩn. Flask phù hợp cho các microservice siêu nhỏ hoặc các bản mẫu (prototype) đơn giản, nơi bạn muốn kiểm soát mọi dòng code từ đầu.

Đối với các dự án API hiện đại, đặc biệt là ứng dụng AI/ML hoặc các hệ thống cần hiệu suất cao, FastAPI nên là lựa chọn mặc định. Nó cân bằng giữa sự linh hoạt và sức mạnh thực thi. Nếu đội ngũ của bạn đã quen với Python type hints, việc chuyển sang FastAPI sẽ mang lại hiệu quả tức thì trong việc giảm lỗi và tăng tốc độ bàn giao tính năng.

Nên bắt đầu với FastAPI từ đâu?

Cách nhanh nhất là cài đặt gói standard để có đầy đủ server và các công cụ bổ trợ. Bạn có thể dùng uv để quản lý gói (nhanh hơn pip) hoặc dùng pip truyền thống:

bash
uv add "fastapi[standard]"
# Hoặc cài bằng pip
pip install "fastapi[standard]"

Sau đó hãy dành thời gian đọc tài liệu chính thức của FastAPI — nó chi tiết, dễ hiểu và đầy ví dụ thực tế. Nếu bạn cần một giải pháp chạy nhanh, an toàn về dữ liệu nhờ Pydantic V2 và không phải tốn công viết tài liệu API bằng tay, thì đây là lựa chọn hợp lý nhất lúc này.

Tài liệu tham khảo

Chia sẻ bài viết

X / TwitterFacebookLinkedIn