FDE PulseViệc làm FDE đang mở 618Mới trong 7 ngày 33Công ty đang tuyển 94Nhận làm từ xa 24%Lương trung vị (Mỹ) $209kTuyển nhiều nhất Databricks 121
EN

Tờ báo của nghề Forward Deployed Engineer

Công cụ

FastAPI: biến model của khách thành API có hợp đồng rõ ràng ngay trong một buổi làm việc

Ở site khách, thứ thuyết phục nhất thường không phải slide mà là một đường link /docs khách bấm thử được ngay, và FastAPI sinh ra đường link đó từ chính code bạn viết.

Ảnh người lập trình viên đang viết code Python trên laptop, hoặc nhóm kỹ sư trao đổi bên bảng trắng tại văn phòng khách hàng.
Ảnh: Emile Perron / Unsplash
Chia sẻLinkedInFacebookX

Tóm tắt nhanh

  • FastAPI dựa trên type hint, Pydantic và chuẩn OpenAPI/JSON Schema, nên schema và tài liệu /docs có sẵn mà không phải viết thêm.
  • response_model vừa lọc bỏ trường không khai báo vừa trả lỗi server thay vì trả dữ liệu sai, tức là hợp đồng được thực thi thật sự.
  • Dự án chưa lên 1.0 (bản 0.157.0 ngày 2026-10-21), vì thế hãy ghim phiên bản trong mọi bản demo giao cho khách.
Sơ đồ hai trạng thái: bên trái, handler trả về ba trường là shipment_id, late_probability và customer_phone. Cả ba đi qua response_model Prediction. Bên phải, client chỉ nhận shipment_id và late_probability. Trường customer_phone bị chặn lại và không rời server.
Pydantic lọc bỏ mọi trường không có trong output model, nên số điện thoại người nhận không bao giờ ra tới app bên ngoài. Nguồn: tài liệu chính thức của FastAPI.

Buổi chiều thứ ba ở site khách, data scientist bên họ đưa bạn một file notebook có model dự đoán đơn hàng giao trễ. Họ hỏi: “Team app có gọi được cái này không?” Câu trả lời tốt nhất trước giờ về là một đường link khách tự bấm thử, có schema rõ ràng và có test đi kèm.

FastAPI được làm ra cho đúng khoảnh khắc đó. Tài liệu chính thức định nghĩa nó là web framework Python để xây API, dựa trên type hint chuẩn của Python. Nó mã nguồn mở theo giấy phép MIT, repo chính thức nằm ở github.com/fastapi/fastapi.

Với một FDE, giá trị nằm ở chỗ một đoạn code sinh ra ba thứ cùng lúc: hợp đồng dữ liệu, tài liệu tương tác và một API test được ngay. Đó là ba thứ khách cần thấy trước khi tin rằng bản demo của bạn có thể đi tiếp vào production.

Vì sao viết code là có luôn tài liệu?

FastAPI xây trên hai chuẩn mở là OpenAPI (trước đây gọi là Swagger) và JSON Schema. Bạn khai báo kiểu dữ liệu bằng type hint và model Pydantic, framework dịch chúng sang schema. Không có bước “viết tài liệu” riêng để rồi quên cập nhật.

Hệ quả cụ thể: chạy app lên là có trang tài liệu tương tác do Swagger UI cung cấp tại /docs, không cần cấu hình gì thêm. Song song đó, toàn bộ mô tả API nằm ở /openapi.json. Team app của khách có thể dùng file này để sinh SDK hoặc kiểm tra hợp đồng mà không phải đọc code của bạn.

Xuất xứ của công cụ cũng khớp với việc bọc model. Sebastián Ramírez (@tiangolo), người tạo ra FastAPI và cả Typer, SQLModel, kể rằng ông đã xây API với yêu cầu phức tạp nhiều năm, gồm machine learning, hệ phân tán và job bất đồng bộ. FastAPI được xây trên nền Pydantic và Starlette.

Một endpoint bọc model, từng dòng một

Thử hình dung model giao trễ ở trên. Bảng dữ liệu nội bộ của khách có cả số điện thoại người nhận, thứ tuyệt đối không được lọt sang app bên ngoài. Endpoint tối thiểu trông như sau, với score_late là hàm giả định gọi model của khách:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class ShipmentIn(BaseModel):
    shipment_id: str
    distance_km: float
    warehouse_id: str

class Prediction(BaseModel):
    shipment_id: str
    late_probability: float

@app.post("/predict", response_model=Prediction)
def predict(shipment: ShipmentIn):
    row = load_shipment(shipment.shipment_id)  # includes customer_phone
    return {
        "shipment_id": shipment.shipment_id,
        "late_probability": score_late(shipment),
        "customer_phone": row["customer_phone"],
    }

Hàm trả về một dict ba trường, nhưng Prediction chỉ khai báo hai. Theo tài liệu, FastAPI dùng Pydantic để lọc bỏ mọi dữ liệu không có trong output model, nên customer_phone không bao giờ rời server. Đây chính là cơ chế bạn cần khi bọc dữ liệu thật của khách: một lỗi sơ ý trong handler không biến thành sự cố rò rỉ.

Ở chiều kia, FastAPI cũng kiểm tra chặt. Nếu handler trả về thứ không khớp Prediction, chẳng hạn thiếu late_probability, FastAPI trả lỗi server thay vì gửi dữ liệu sai đi. Response model còn gắn JSON Schema của đầu ra vào OpenAPI, nên trang /docs mô tả đúng những gì team app sẽ nhận.

Test trong cùng buổi, không cần dựng server

Bản demo chỉ đáng tin khi có test, và đây là chỗ FastAPI giữ chi phí thấp. Bạn chỉ cần cài thêm httpx rồi dùng pytest. TestClient xây trên HTTPX nên test chạy ngay trong tiến trình, không phải khởi động server hay mở cổng.

from fastapi.testclient import TestClient
from app import app

client = TestClient(app)

def test_phone_never_leaks():
    r = client.post("/predict", json={
        "shipment_id": "S-001",
        "distance_km": 12.5,
        "warehouse_id": "HCM-1",
    })
    assert r.status_code == 200
    assert "customer_phone" not in r.json()

Hàm test là def thường, không phải async def, kể cả khi endpoint là async. Điều đó giúp bạn viết test ngay trong buổi làm việc, thậm chí ngồi cùng kỹ sư bên khách. Test này nên là thứ đầu tiên bạn viết: nó biến lời hứa “không lộ dữ liệu cá nhân” thành một dòng assert ai cũng đọc được.

Hai lỗi dễ mắc khi bọc dữ liệu thật

Cơ chế lọc ở trên dựa vào output model; không có model đó thì cũng không còn danh sách trường nào để FastAPI đối chiếu. Hậu quả dễ suy ra: handler trả gì, client có nguy cơ nhận nấy, kể cả customer_phone.

Lỗi thứ hai là trả thẳng object ORM hay nguyên một dòng lấy từ bảng của khách. Hôm nay bảng có năm cột vô hại, tháng sau team dữ liệu thêm cột thông tin cá nhân, và nếu không có lớp lọc thì cột mới đi theo ra ngoài mà không ai hay.

Thói quen an toàn là luôn đi qua một model đầu ra riêng, kể cả khi nó trùng gần hết với bảng. Rồi giữ test kiểu test_phone_never_leaks trong bộ test, để nếu ai đó lỡ xoá response_model, test đỏ trước khi khách nhìn thấy dữ liệu lọt ra.

Giới hạn cần nói thẳng với khách

FastAPI vẫn chưa lên 1.0. Trang release notes chính thức ghi bản 0.157.0 ngày 2026-10-21, cho thấy dự án vẫn ra bản mới nhưng còn ở giai đoạn 0.x. Lời khuyên thực tế là ghim chính xác phiên bản trong file dependency của mọi bản demo bàn giao, để vài tháng sau khách cài lại vẫn chạy y nguyên.

Giới hạn thứ hai là về phạm vi. FastAPI lo lớp hợp đồng và giao tiếp HTTP, chứ không làm model của khách nhanh hơn hay đúng hơn. Nếu model mất vài giây cho mỗi dự đoán, endpoint đẹp đến mấy cũng chậm chừng đó, và bạn vẫn phải tự giải quyết chuyện vận hành ở môi trường của khách.

Học gì trước, và ghi gì vào CV

Thứ tự hợp lý là type hint và model Pydantic trước, vì mọi thứ còn lại sinh ra từ đó. Tiếp theo là response_model, rồi TestClient. Ba mảnh này đủ để bạn đi từ notebook đến API có tài liệu và test trong một buổi chiều.

Nếu một mô tả việc FDE nhắc đến dựng prototype hay tích hợp với hệ thống của khách, đây là kỹ năng đáng đem ra kể. Trên CV, đừng chỉ ghi “FastAPI” trong danh sách kỹ năng.

Một dòng kiểu “bọc model dự đoán của khách thành API có schema OpenAPI, test tự động chặn rò rỉ dữ liệu cá nhân, bàn giao trong một ngày” kể được cả kỹ thuật lẫn cách bạn làm việc với khách.

Lần tới có người hỏi “team app có gọi được cái này không”, câu trả lời của bạn nên là một đường link /docs và một test xanh.

Bài này có hữu ích không?

Dùng cùng trợ lý AIHỏi Claude ↗Hỏi ChatGPT ↗
8 nguồn
Đọc tiếp trên lộ trình · Chặng 2: Kỹ thuật rộngZod: chặn dữ liệu sai từ API của khách trước khi agent đọc nóỞ site khách, API trả về sai một trường là đủ khiến agent ra quyết định sai. Một schema Zod đặt ở lối vào giúp bạn phát hiện lỗi đó trước khi agent đọc dữ liệu.