本文 AI 產出,尚未審核

FastAPI 教學:在路由中使用 summarydescription 提升 API 文件品質


簡介

在開發 RESTful API 時,除了功能正確之外,文件的可讀性 直接影響到前端、測試人員以及日後維護的成本。FastAPI 內建支援 OpenAPI(也就是 Swagger)與 ReDoc,讓開發者只要在程式碼中加入少量的註解,就能自動產生完整、互動式的 API 文件。

其中最常被忽略的兩個屬性是 summarydescriptionsummary 用於簡短說明一個端點的目的,會出現在 Swagger UI 左側的列表;description 則是較詳細的說明,可支援 Markdown,會在點擊端點後顯示於說明區。善用這兩個欄位,不僅能讓文件更易讀,還能幫助團隊快速了解每個路由的行為與使用方式。

本篇文章將從概念說明、實作範例、常見陷阱與最佳實踐,最後帶出實務應用場景,完整介紹如何在 FastAPI 路由中使用 summarydescription,讓你的 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…)內加入 summarydescription,這些資訊就會被寫入 OpenAPI 檔案,進而呈現在 Swagger UI 與 ReDoc 中。

2. summarydescription 的差異與用途

屬性 顯示位置 內容長度 支援 Markdown
summary Swagger 左側列表、ReDoc 標題 短句(建議 ≤ 120 字) ❌(純文字)
description 點擊後的詳細說明區、ReDoc 內文 多段落、程式碼片段等 ✅(支援)
  • summary:適合放置「這個端點做什麼」的概括說明,例如「取得使用者資訊」或「新增訂單」。
  • description:可說明參數的限制、業務流程、範例請求/回應,甚至插入程式碼區塊,讓文件更具說服力。

3. 在 FastAPI 中設定 summarydescription

FastAPI 的路由裝飾器接受 summarydescription 兩個關鍵字參數。範例如下:

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 個常見情境的範例,說明如何在不同類型的路由中運用 summarydescription

範例 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 語法。
忘記在 PathQuery 等參數上加說明 產生的文件只顯示型別,使用者不清楚限制。 PathQueryBodydescription 參數裡補充說明;或使用 Pydantic Field
重複或不一致的說明 文件與實際行為不符,造成開發者困惑。 單一來源 原則:在程式碼中寫一次,盡量避免在 README 或外部文件重複敘述。
未設定回應模型 Swagger 只顯示 application/json,但缺少結構。 使用 response_model 參數,讓文件自動產生回應欄位。

最佳實踐

  1. 保持 summary 簡潔:一句話概括功能,字數控制在 80–120 之間。
  2. description 用 Markdown 撰寫:加入段落、清單、程式碼範例,提升可讀性。
  3. 配合 Pydantic Field:在模型內直接寫說明,會自動匯入到 OpenAPI。
  4. 使用 response_model:讓回傳結構清晰、文件自動生成。
  5. 測試文件:啟動 FastAPI 後,瀏覽 /docs/redoc,確認說明是否正確顯示。

實際應用場景

1. 內部微服務平台

在企業內部的微服務環境,開發團隊往往需要快速了解其他服務的 API。透過 summarydescription,每個端點的功能與使用方式一目了然,減少溝通成本。

2. 第三方合作夥伴 API

當你提供給外部合作夥伴的 API 時,文件的完整度直接影響合作速度。使用 description 包含 授權方式、錯誤代碼、範例請求,可讓合作方直接在 Swagger UI 測試,縮短整合時間。

3. 前端與行動端開發

前端開發者常在 Swagger UI 中直接撰寫測試請求。若每個端點都有清楚的 summarydescription,他們能快速找到正確的參數名稱與限制,降低前後端不一致的 bug。

4. 自動化測試與文件生成

CI/CD 流程中,可將 /openapi.json 作為測試基礎,檢查是否有缺失說明或不一致的欄位。再配合工具(如 redoc-cli)產出正式 PDF 文件,提供給非技術人員閱讀。


總結

  • summarydescription 是 FastAPI 生成高品質 OpenAPI 文件的關鍵。
  • summary 用於簡短概述,保持一句話description 支援 Markdown,可加入範例、清單與程式碼
  • 正確使用這兩個屬性不僅提升 Swagger UI / ReDoc 的可讀性,還能減少團隊溝通成本、加速前後端協作。
  • 在實務開發中,務必結合 Pydantic Fieldresponse_model測試文件,確保說明與實作同步。

透過本文的概念與範例,即可在 FastAPI 專案中快速為每個路由添加清晰、完整的說明,讓你的 API 文件從「能看」變成「好用」!祝開發順利 🚀