API Academy
🌐 繁體中文
  • 🌐 English
  • 🌐 繁體中文
HomePetstore APIExplore more APIs
HomePetstore APIExplore more APIs
🌐 繁體中文
  • 🌐 English
  • 🌐 繁體中文
🌐 繁體中文
  • 🌐 English
  • 🌐 繁體中文
  1. Developing APIs
  • 歡迎
  • 目錄
  • API 學院
    • Get Started
      • 什麼是 API?
      • API 如何運作?
      • 如何呼叫 API?
      • 如何閱讀 API 文件?
      • 章節總結
    • API Fundamentals
      • API 基礎知識:概覽
      • 方法與路徑
      • 參數
      • 請求 Body
      • 回應
      • API 規格與 OAS
      • 章節總結
    • Working with APIs
      • 使用 API:概覽
      • 根據規格發送請求
      • 環境與變數
      • 串聯多個端點
      • 處理 Auth
      • 處理 API 簽名
      • 腳本介紹
      • 章節總結
    • Mocking APIs
      • Mocking API:概覽
      • Smart Mock
      • Mock 預期結果
      • Cloud Mock
      • Mock 腳本
      • 章節總結
    • Designing APIs
      • 設計 API:概覽
      • API 設計介紹
      • 建立您的第一個 API 專案
      • 分析需求並規劃您的 API
      • 設計資料模型
      • 設計端點
      • 使用組件與可重用性
      • 設定與 Auth
      • API 設計指南
      • 章節總結
    • Developing APIs
      • 開發 API:概覽
      • 設定:安裝您的 AI 程式碼助手
      • 快速入門:30 分鐘內從規格到運行的 API
      • 了解生成的程式碼
      • 使用 Apidog 測試您的 API
      • 部署:將您的 API 上線
      • 章節總結
    • Testing APIs
      • 測試 API:概覽
      • 快速入門:您的第一個測試場景
      • 整合測試與資料傳遞
      • 動態值
      • 斷言與驗證
      • 流程控制:If, For, ForEach
      • 資料驅動測試
      • 性能測試
      • 測試報告與分析
      • CI/CD 整合
      • 排程任務與自動化
      • 進階測試策略
      • 章節總結
    • API Documentations
      • API 文件:概覽
      • 發布您的第一個 API 文件
      • 自訂文件外觀
      • 給消費者的互動功能
      • 進階發布設定
      • 管理 API 版本
      • 章節總結
    • Advanced API Technologies
      • 進階 API 技術:概覽
      • GraphQL
      • gRPC
      • WebSocket
      • Socket.IO
      • Server-Sent Events
      • SOAP
      • 章節總結
    • API Lifecycle
      • API 生命周期:概覽
      • API 生命周期的階段
      • API 治理
      • API 安全最佳實踐
      • 監控與分析
      • API 版本策略
      • API 的未來
      • 章節總結
    • API Security
      • API 安全性:概覽
      • API 安全性基礎知識
      • 身份驗證 vs. 授權
      • 了解 OAuth 2.0 和 OpenID Connect
      • JSON Web Tokens (JWT)
      • OWASP API 安全 Top 10
      • 加密與 HTTPS
      • 章節總結
    • API Tools
      • API 工具:概覽
      • API 工具的演變
      • API Clients
      • 命令列工具 (cURL, HTTPie)
      • API 設計和文件工具
      • API Mocking 工具
      • API 測試工具
      • 一體化 API 平台
      • 章節總結
    • API Gateway
      • API Gateway:概覽
      • 什麼是 API Gateway?
      • API Gateway 的關鍵功能
      • API Gateway vs 負載平衡器 vs 服務網格
      • 流行 API Gateway 解決方案
      • BFF (Backend for Frontend) 模式
      • 章節總結
HomePetstore APIExplore more APIs
HomePetstore APIExplore more APIs
🌐 繁體中文
  • 🌐 English
  • 🌐 繁體中文
🌐 繁體中文
  • 🌐 English
  • 🌐 繁體中文
  1. Developing APIs

了解生成的程式碼

您的 API 正在執行。您可以在 http://localhost:8000/docs 看到它在運作。但在 Cursor 生成的那些檔案中究竟發生了什麼事?
本章將引導您瀏覽程式碼,讓您了解您正在使用的內容。我們將探索每個檔案,解釋關鍵概念,並向您展示如何使用 Cursor 本身作為學習工具。讀完本章,您將了解您的 API 實際上是如何運作的。

使用 Cursor 來學習程式碼#

在我們深入探討之前,這裡有一個技巧可以讓理解程式碼變得容易得多:要求 Cursor 解釋它。
說真的。編寫程式碼的 AI 可以解釋程式碼。方法如下:
1.
選擇任何一段您不理解的程式碼
2.
按 Cmd+K (Mac) 或 Ctrl+K (Windows/Linux)
3.
詢問:"解釋這段程式碼做什麼" 或 "為什麼我們需要這個?"
4.
Cursor 會用淺顯的語言解釋它
您還可以:
詢問 "這個函式做什麼?"
詢問 "這如何與資料庫運作?"
詢問 "為什麼要這樣寫?"
當我們瀏覽檔案時,請儘管使用這個功能。我會解釋大局,但如果您想要任何特定部分的更多細節,只需詢問 Cursor。

專案結構概覽#

在 Cursor 中打開您的專案。您應該會看到類似這樣的內容:
user-api/
├── main.py              # 入口點 - 啟動 API
├── database.py          # 資料庫設定和連接
├── auth.py              # JWT token 函式
├── dependencies.py      # 可重複使用的元件
├── models/
│   └── user.py         # 資料庫表定義
├── schemas/
│   └── user.py         # API 請求/回應格式
├── routers/
│   └── users.py        # 您所有的端點
├── requirements.txt     # 依賴項
├── .env.example        # 環境變數範本
├── README.md           # 設定說明
└── users.db            # SQLite 資料庫(首次執行後出現)
將此結構視為分層:
入口點 (main.py) 建立 API 並連接一切。
路由器 (routers/users.py) 處理每個端點的 HTTP 請求。
Schemas (schemas/user.py) 定義資料在請求和回應中的樣子。
Models (models/user.py) 定義資料在資料庫中的樣子。
資料庫 (database.py) 管理與 SQLite 的連接。
Auth (auth.py) 處理用於身分驗證的 JWT tokens。
依賴項 (dependencies.py) 提供可重複使用的函式,如「獲取當前使用者」。
讓我們瀏覽每個檔案。

main.py - 入口點#

打開 main.py。這是萬物開始的地方。
您將看到的內容:
發生了什麼事:
該檔案建立了您的 FastAPI 應用程式。就是 app = FastAPI() 那一行。其他一切都是配置。
Base.metadata.create_all() 自動建立您的資料庫表。第一次執行 API 時,它會發現您沒有 users 表並建立它。這就是為什麼您不需要執行單獨的資料庫設定指令。
CORS middleware 允許您的 API 接收來自網頁瀏覽器的請求。在開發中,它是完全開放的 (allow_origins=["*"])。在生產環境中,您會限制為特定網域。
app.include_router(users.router) 連接您所有的使用者端點。沒有這一行,端點將無法訪問。
就是這樣。入口點出奇地簡單,因為所有真正的工作都發生在其他檔案中。

database.py - 資料庫連接#

此檔案設定與 SQLite 資料庫的連接。
您將看到的內容:
了解各個部分:
engine 是您的資料庫連接。它知道如何與 SQLite 對話。
SessionLocal 建立資料庫工作階段 (sessions)。每次您想與資料庫互動時,您會建立一個工作階段,完成工作,然後關閉它。
Base 是您的模型繼承的基礎。還記得 models/user.py 嗎?它使用這個 Base 來成為資料庫表。
get_db() 是一個函式,它給您一個資料庫工作階段,並在您完成後自動關閉它。這透過 FastAPI 的依賴注入在整個 API 中使用。
為什麼是 SQLite?
對於開發來說,SQLite 很完美。它只是一個檔案 (users.db),無需管理單獨的伺服器。當您部署到生產環境時,您只需更改一行即可使用 PostgreSQL。其餘程式碼保持不變,因為 SQLAlchemy (ORM) 抽象了資料庫差異。

models/user.py - 資料庫表#

這定義了您的 users 表在資料庫中的樣子。
您將看到的內容:
這是您的資料庫 schema。 每個 Column 都會成為 users 表中的一列。
一些有趣的細節:
id 使用 UUID (通用唯一識別碼),看起來像 "a8f3c2e1-4b7d-4e9a-b3c1-8f2d3e4a5b6c"。default=lambda: str(uuid.uuid4()) 會在您建立使用者時自動生成一個新的隨機 ID。
email 有 unique=True,這意味著資料庫將拒絕重複的電子郵件。它還有 index=True 以加快查詢速度。
nullable=False 表示該欄位是必需的。nullable=True 表示它是可選的。
注意這裡有一個 password 欄位。這儲存雜湊後的密碼(不是純文字)。我們將在查看路由器時看到雜湊是如何運作的。
Models vs Schemas:
不要混淆 models/user.py 和 schemas/user.py:
Models 定義資料庫表(儲存什麼)
Schemas 定義 API 資料格式(發送/接收什麼)
它們很相似但服務於不同目的。您稍後會明白為什麼我們兩者都需要。

schemas/user.py - API 資料格式#

這定義了資料在您的 API 請求和回應中的樣子。
您將看到的內容:
為什麼有三個不同的 schemas?
每一個都服務於特定目的:
UserCreate 是客戶端在建立使用者時發送的內容。它包含密碼,因為他們需要設定密碼。它驗證電子郵件實際上是電子郵件格式 (EmailStr)。
UserResponse 是 API 返回的內容。注意它不包含密碼。這是一個安全功能。密碼欄位是唯寫的 - 您可以發送它,但永遠拿不回來。
UserUpdate 用於更新使用者。所有欄位都是 Optional,因為您可能只想更新 firstName 而不更改其他任何內容。
Pydantic 的作用:
這些 schemas 使用 Pydantic,它會自動驗證資料。如果有人發送 "email": "not-an-email",Pydantic 會在您的程式碼執行之前拒絕它。如果他們發送 "age": 25 但 age 不在您的 schema 中,Pydantic 會忽略它。
這就是為什麼 FastAPI 如此強大 - 透過定義這些 schemas,您即可獲得自動驗證和自動文件。

routers/users.py - 您的端點#

這是真正工作發生的地方。打開 routers/users.py,您將看到所有六個端點。
讓我們瀏覽幾個關鍵的:

POST /users - 建立使用者#

分解動作:
@router.post("/users") 說「此函式處理對 /users 的 POST 請求」
response_model=UserResponse 告訴 FastAPI 使用 UserResponse schema 格式化回應(排除密碼)
status_code=201 設定成功建立的 HTTP 狀態碼
user: UserCreate 意味著 FastAPI 將自動解析請求 body 為 JSON 並根據 UserCreate schema 進行驗證
db: Session = Depends(get_db) 是 FastAPI 的依賴注入。它從 database.py 調用 get_db(),給您一個資料庫工作階段。當函式結束時,工作階段自動關閉。
邏輯流程:
1.
檢查電子郵件是否已存在(防止重複)
2.
使用 bcrypt 雜湊密碼(絕不儲存純文字)
3.
使用資料建立 User model 實例
4.
將其新增到資料庫工作階段
5.
提交交易(實際儲存到資料庫)
6.
重新整理以獲取生成的欄位(如 id, createdAt)
7.
返回使用者(FastAPI 自動將其轉換為 UserResponse 格式)

POST /user/login - 登入#

發生了什麼事:
透過電子郵件尋找使用者。如果未找到,返回 401(不要告訴客戶端是電子郵件存在還是密碼錯誤 - 這是一個安全慣例)。
使用 bcrypt 驗證密碼。它將提交的密碼雜湊,並將其與儲存的雜湊進行比較。如果匹配,密碼正確。
如果有效,建立一個包含使用者 ID 的 JWT token(sub 是 "subject" 的標準 JWT 欄位)。
返回 token。客戶端將在受保護端點的 Authorization header 中包含此 token。

PUT /users/{id} - 更新使用者(受保護)#

注意區別:
current_user: User = Depends(get_current_user) - 此端點需要身分驗證。get_current_user 依賴項從 Authorization header 中提取 JWT token,驗證它,並載入使用者。如果 token 無效或遺失,請求甚至在執行此函式之前就會失敗。
if current_user.id != id: - 使用者只能更新自己的帳戶。即使擁有有效 token,您也不能修改其他人的資料。
user_update.dict(exclude_unset=True) - 僅更新實際提供的欄位。如果客戶端發送 {"firstName": "NewName"},則只有 firstName 改變。exclude_unset=True 忽略請求中沒有的欄位。

auth.py - JWT Token 處理#

此檔案包含身分驗證邏輯。
您將看到的內容:
了解 JWT:
當使用者登入時,create_access_token() 建立一個 JWT token。此 token 是一個包含使用者 ID 和過期時間的加密簽章字串。簽章使用 SECRET_KEY,因此 token 無法偽造。
Token 在 24 小時後過期 (ACCESS_TOKEN_EXPIRE_HOURS)。之後,使用者需要再次登入。
了解密碼雜湊:
hash_password() 獲取純密碼如 "SecurePass123" 並將其轉換為類似 "$2b$12$KIXxE.j3vFg9QN8hA6Fv0e..." 的東西。這是一個單向轉換 - 您無法反轉它以獲得原始密碼。
verify_password() 獲取純密碼和雜湊,雜湊純密碼,並比較雜湊。如果它們匹配,則密碼正確。
這意味著即使您的資料庫被入侵,攻擊者也無法獲得實際密碼。

dependencies.py - 可重複使用的元件#

這做了什麼:
HTTPBearer() 從請求中提取 Authorization: Bearer <token> header。
get_current_user() 是受保護端點使用的依賴項。它:
1.
從 Authorization header 獲取 token
2.
解碼並驗證 JWT
3.
從 token 中提取使用者 ID
4.
從資料庫載入使用者
5.
返回使用者物件
如果任何步驟失敗(遺失 token、無效簽章、過期 token、使用者已刪除),它會引發 401 錯誤。
這就是為什麼受保護端點只需使用 Depends(get_current_user) 即可自動訪問經過驗證的使用者。依賴項系統非常優雅。

一切如何組合在一起#

讓我們在系統中追踪一個完整的請求。假設客戶端想要更新他們的名字:
1. 請求到達:
PUT /users/abc123
Authorization: Bearer eyJhbGc...
{"firstName": "NewName"}
2. FastAPI 路由(在 main.py 中)看到這與 routers/users.py 中的 PUT /users/{id} 端點匹配
3. 依賴注入執行:
get_db() 建立資料庫工作階段
get_current_user() 驗證 JWT token 並載入使用者
4. Pydantic 驗證 將請求 body 解析為 UserUpdate schema 並驗證它
5. 端點函式執行:
檢查當前使用者是否與 ID 匹配
更新使用者的 firstName
提交到資料庫
6. 回應格式化:
FastAPI 將 User model 轉換為 UserResponse schema
排除密碼欄位
返回 JSON
7. 客戶端接收:
{
  "id": "abc123",
  "email": "user@example.com",
  "firstName": "NewName",
  ...
}
所有這些都自動發生。您只需在端點函式中編寫商業邏輯。

關鍵概念總結#

既然您已經看過程式碼,以下是重要的模式:
三層架構:
Routers 處理 HTTP(請求和回應)
Schemas 定義 API 資料格式(驗證)
Models 定義資料庫結構(持久化)
依賴注入:
FastAPI 的 Depends() 自動提供資料庫工作階段、當前使用者等。這保持程式碼乾淨並處理設定/清理。
自動驗證:
Pydantic schemas 自動驗證所有輸入。壞資料永遠不會到達您的程式碼。
設計上的安全性:
密碼被雜湊 (bcrypt)
密碼絕不包含在回應中 (schema 排除)
JWT tokens 會過期 (限時存取)
使用者只能修改自己的資料 (授權檢查)
資料庫抽象:
SQLAlchemy ORM 意味著您編寫 Python,而不是 SQL。從 SQLite 切換到 PostgreSQL 只是更改連接字串。

您學到了什麼#

您現在了解:
專案是如何結構化的以及為什麼
每個檔案做什麼以及它們如何協同工作
請求如何在 API 中流動
身分驗證如何運作 (JWT)
安全性是如何內建的 (雜湊、驗證、授權)
資料庫整合如何運作
更重要的是,您知道如何使用 Cursor 來探索程式碼。選擇任何您不理解的東西,按 Cmd+K,然後提問。生成此程式碼的 AI 是您的學習夥伴。

下一步是什麼#

理解程式碼是一回事。將其變成您的又是另一回事。
在下一章中,您將學習如何自訂和擴充此 API。想新增新欄位?更改某些運作方式?新增全新的功能?我們將向您展示如何使用 Cursor 快速且正確地進行這些更改。
繼續閱讀 → 使用 Apidog 測試您的 API
首先,讓我們確保一切實際上都運作正常,透過在 Apidog 中正確地測試它。
Modified at 2025-12-29 09:35:19
Previous
快速入門:30 分鐘內從規格到運行的 API
Next
使用 Apidog 測試您的 API
Built with