FastAPI 教學:在路由中使用 summary 與 description 提升 API 文件品質
簡介
在開發 RESTful API 時,除了功能正確之外,文件的可讀性 直接影響到前端、測試人員以及日後維護的成本。FastAPI 內建支援 OpenAPI(也就是 Swagger)與 ReDoc,讓開發者只要在程式碼中加入少量的註解,就能自動產生完整、互動式的 API 文件。
其中最常被忽略的兩個屬性是 summary 與 description。summary 用於簡短說明一個端點的目的,會出現在 Swagger UI 左側的列表;description 則是較詳細的說明,可支援 Markdown,會在點擊端點後顯示於說明區。善用這兩個欄位,不僅能讓文件更易讀,還能幫助團隊快速了解每個路由的行為與使用方式。
本篇文章將從概念說明、實作範例、常見陷阱與最佳實踐,最後帶出實務應用場景,完整介紹如何在 FastAPI 路由中使用 summary 與 description,讓你的 API 文件從「可用」升級為「好用」。
核心概念
1. OpenAPI、Swagger 與 ReDoc 的關係
- OpenAPI:一套規範,用 JSON 或 YAML 描述 API 的結構、參數、回應等資訊。
- Swagger UI:根據 OpenAPI 規範產生的互動式前端,讓使用者直接在瀏覽器測試 API。
- ReDoc:另一種基於 OpenAPI 的文件呈現方式,外觀較為正式、適合正式文件。
FastAPI 會在啟動時自動產生 /openapi.json、/docs(Swagger UI)與 /redoc(ReDoc)三個端點。開發者只要在路由裝飾器(@app.get、@app.post…)內加入 summary、description,這些資訊就會被寫入 OpenAPI 檔案,進而呈現在 Swagger UI 與 ReDoc 中。
2. summary 與 description 的差異與用途
| 屬性 | 顯示位置 | 內容長度 | 支援 Markdown |
|---|---|---|---|
summary |
Swagger 左側列表、ReDoc 標題 | 短句(建議 ≤ 120 字) | ❌(純文字) |
description |
點擊後的詳細說明區、ReDoc 內文 | 多段落、程式碼片段等 | ✅(支援) |
summary:適合放置「這個端點做什麼」的概括說明,例如「取得使用者資訊」或「新增訂單」。description:可說明參數的限制、業務流程、範例請求/回應,甚至插入程式碼區塊,讓文件更具說服力。
3. 在 FastAPI 中設定 summary 與 description
FastAPI 的路由裝飾器接受 summary、description 兩個關鍵字參數。範例如下:
from fastapi import FastAPI, Path
app = FastAPI()
@app.get(
"/users/{user_id}",
summary="取得單一使用者資訊",
description="""
依照 **user_id** 取得使用者詳細資料。
- `user_id` 必須是正整數
- 若使用者不存在,回傳 **404 Not Found**
### 範例請求
```http
GET /users/123 HTTP/1.1
Host: api.example.com
```
### 範例回應
```json
{
"id": 123,
"name": "Alice",
"email": "alice@example.com"
}
```
"""
)
def read_user(user_id: int = Path(..., gt=0)):
# 這裡實作查詢資料庫的邏輯
return {"id": user_id, "name": "Alice", "email": "alice@example.com"}
上述程式碼示範了 summary 的簡短敘述與 description 中使用 Markdown(包括清單、程式碼區塊與粗體)來提供更完整的說明。
程式碼範例
以下提供 4 個常見情境的範例,說明如何在不同類型的路由中運用 summary 與 description。
範例 1:POST 建立資源,說明請求與回應格式
from fastapi import FastAPI, Body
from pydantic import BaseModel, EmailStr
app = FastAPI()
class UserCreate(BaseModel):
name: str
email: EmailStr
@app.post(
"/users",
summary="建立新使用者",
description="""
接收 JSON 格式的使用者資訊,建立後回傳 **201 Created** 與新使用者的 ID。
**注意**:
- `email` 必須符合 Email 格式
- `name` 不能為空字串
```json
{
"name": "Bob",
"email": "bob@example.com"
}
```
"""
)
def create_user(user: UserCreate = Body(...)):
# 假設寫入資料庫,回傳新 ID
new_id = 42
return {"id": new_id, **user.dict()}
範例 2:PUT 更新全部欄位,說明部分更新的限制
from fastapi import FastAPI, Path, Body
app = FastAPI()
class UserUpdate(BaseModel):
name: str | None = None
email: EmailStr | None = None
@app.put(
"/users/{user_id}",
summary="更新使用者全部資訊",
description="""
使用 **PUT** 代表要提供完整的資源表示,若欄位為 `null`,將被視為 **清除**。
若只想更新部分欄位,請改用 **PATCH**。
### 範例請求
```json
{
"name": "Charlie",
"email": null
}
```
"""
)
def update_user(
user_id: int = Path(..., gt=0),
payload: UserUpdate = Body(...)
):
# 更新邏輯
return {"id": user_id, **payload.dict()}
範例 3:GET 查詢列表,說明 query 參數的分頁與過濾
from fastapi import FastAPI, Query
from typing import List
app = FastAPI()
@app.get(
"/items",
summary="取得商品清單",
description="""
支援以下 query 參數:
- `skip` (int): 跳過前幾筆資料,預設 `0`
- `limit` (int): 回傳筆數上限,預設 `10`,最大 `100`
- `category` (str, optional): 依類別過濾
### 範例請求
```
GET /items?skip=20&limit=5&category=books
```
"""
)
def list_items(
skip: int = Query(0, ge=0),
limit: int = Query(10, le=100),
category: str | None = None,
):
# 假資料
dummy = [{"id": i, "name": f"Item {i}", "category": "books"} for i in range(skip, skip + limit)]
if category:
dummy = [item for item in dummy if item["category"] == category]
return dummy
範例 4:DELETE 刪除資源,說明安全性考量
from fastapi import FastAPI, Path, HTTPException, status
app = FastAPI()
@app.delete(
"/users/{user_id}",
summary="刪除使用者",
description="""
**重要**:此操作不可逆,請務必確認 `user_id` 正確。
- 成功時回傳 **204 No Content**
- 若目標不存在,回傳 **404 Not Found**
建議在前端加入二次確認對話框,以降低誤刪的風險。
"""
)
def delete_user(user_id: int = Path(..., gt=0)):
# 假設查無此人
if user_id != 1:
raise HTTPException(status_code=404, detail="User not found")
# 執行刪除
return {"detail": "Deleted"} # Swagger 會自動顯示 200,若想回 204 可自行設定
常見陷阱與最佳實踐
| 陷阱 | 說明 | 解決方案 |
|---|---|---|
summary 文字過長 |
超過 120 字會在 Swagger UI 被截斷,影響閱讀。 | 只寫 一句話,必要時把細節放到 description。 |
description 未使用 Markdown |
失去格式化的優勢,文件顯得雜亂。 | 使用三重反引號 ``` 包住程式碼、使用 *、-、# 等 Markdown 語法。 |
忘記在 Path、Query 等參數上加說明 |
產生的文件只顯示型別,使用者不清楚限制。 | 在 Path、Query、Body 的 description 參數裡補充說明;或使用 Pydantic Field。 |
| 重複或不一致的說明 | 文件與實際行為不符,造成開發者困惑。 | 單一來源 原則:在程式碼中寫一次,盡量避免在 README 或外部文件重複敘述。 |
| 未設定回應模型 | Swagger 只顯示 application/json,但缺少結構。 |
使用 response_model 參數,讓文件自動產生回應欄位。 |
最佳實踐
- 保持
summary簡潔:一句話概括功能,字數控制在 80–120 之間。 description用 Markdown 撰寫:加入段落、清單、程式碼範例,提升可讀性。- 配合 Pydantic
Field:在模型內直接寫說明,會自動匯入到 OpenAPI。 - 使用
response_model:讓回傳結構清晰、文件自動生成。 - 測試文件:啟動 FastAPI 後,瀏覽
/docs或/redoc,確認說明是否正確顯示。
實際應用場景
1. 內部微服務平台
在企業內部的微服務環境,開發團隊往往需要快速了解其他服務的 API。透過 summary 與 description,每個端點的功能與使用方式一目了然,減少溝通成本。
2. 第三方合作夥伴 API
當你提供給外部合作夥伴的 API 時,文件的完整度直接影響合作速度。使用 description 包含 授權方式、錯誤代碼、範例請求,可讓合作方直接在 Swagger UI 測試,縮短整合時間。
3. 前端與行動端開發
前端開發者常在 Swagger UI 中直接撰寫測試請求。若每個端點都有清楚的 summary 與 description,他們能快速找到正確的參數名稱與限制,降低前後端不一致的 bug。
4. 自動化測試與文件生成
CI/CD 流程中,可將 /openapi.json 作為測試基礎,檢查是否有缺失說明或不一致的欄位。再配合工具(如 redoc-cli)產出正式 PDF 文件,提供給非技術人員閱讀。
總結
summary與description是 FastAPI 生成高品質 OpenAPI 文件的關鍵。summary用於簡短概述,保持一句話;description支援 Markdown,可加入範例、清單與程式碼。- 正確使用這兩個屬性不僅提升 Swagger UI / ReDoc 的可讀性,還能減少團隊溝通成本、加速前後端協作。
- 在實務開發中,務必結合 Pydantic
Field、response_model與 測試文件,確保說明與實作同步。
透過本文的概念與範例,即可在 FastAPI 專案中快速為每個路由添加清晰、完整的說明,讓你的 API 文件從「能看」變成「好用」!祝開發順利 🚀