iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
生成式 AI

從系統設計切入,探索 GenAI 在企業中的實踐系列 第 27

[Day27] OpenAPI 規範:基礎介紹與 FastAPI 的自動化 API 配置

  • 分享至 

  • xImage
  •  

在現代微服務架構中,隨著 API 數量不斷增多,如何有效地管理 API 成為後端開發中的一大挑戰。API Gateway 作為一個統一的入口,幫助我們控制外部流量,實現認證與授權、路由選擇,並提供限流和監控等功能。相較於 Load Balancer 的簡單流量分配,API Gateway 提供了更精細的 API 控制,允許我們在 API 層進行版本管理、限流以及安全性加強。

同時,OpenAPI 規範提供了一個標準化的方法來描述 API,使得開發者能夠定義 API 的行為、參數、回應和認證機制,並自動生成文檔來提升系統的透明度與可擴展性。即便是使用像 FastAPI 這樣的框架進行 API 開發,理解 OpenAPI 與 API Gateway 的配置仍然是提升系統設計和管理能力的關鍵。因此,本文將展示如何利用 API Gateway 管理 API 流量、限流、安全認證等關鍵功能,並結合 FastAPI 與 OpenAPI 的自動整合來提升開發效率。

OpenAPI YAML 配置

基本資訊設置

  • 什麼是 OpenAPI:OpenAPI 是一個標準化的 API 描述規範,它允許開發者使用 YAML 或 JSON 來精確描述 API 的路徑、參數、認證方式、回應格式等。
  • 為什麼選擇 OpenAPI:OpenAPI 不僅能自動生成文檔,還可以用於生成用戶端 SDK、進行 API 測試,以及設置 API 的安全和版本控制。
openapi: '3.0.0'
info:
  title: Example API
  description: This is an example API following the OpenAPI specification.
  version: '1.0'
  • openapi:使用的 OpenAPI 規範版本。
  • info:包含 API 的基本資訊,其中 title 是 API 的名稱,description 提供 API 的簡短描述,version 表示該 API 的版本號。

路由和請求方法

  • 定義 API 路徑:通過 OpenAPI,我們可以定義每個 API 的 URL 路徑和對應的 HTTP 請求方法(如 GET、POST 等)。
  • 設置請求參數和回應格式:每個路徑可以接受不同類型的請求參數,這些參數可以是路徑參數、查詢參數或表單數據。OpenAPI 允許我們精確描述這些參數的類型和是否為必填項。
# Paths (API Endpoints)
paths:
  /items/{item_id}:
    get:
      summary: Retrieve an item by its ID
      parameters:
        - name: item_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: A successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  item_id:
                    type: integer
                  name:
                    type: string
                example:
                  item_id: 1
                  name: "Example item"

展示如何為路徑 /items/{item_id} 定義一個 GET 請求,其中包括一個必填的路徑參數 item_id,並且定義了 200 成功回應的 JSON 結構。

API 版本管理

  • 版本控制的重要性:在 API 開發過程中,隨著應用的發展,API 的結構和行為會不斷變化。通過版本控制,我們可以同時支持不同的 API 版本,讓使用者能夠逐步過渡到新版 API。
  • 定義不同版本的 API 路徑:版本控制的一種常見方式是將版本號包含在 API 路徑中,例如 /v1/ 或 /v2/。
paths:
  /v1/items/{item_id}:
    get:
      summary: Retrieve an item by its ID (Version 1)
      parameters:
        - name: item_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: A successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  item_id:
                    type: integer
                  name:
                    type: string
                example:
                  item_id: 1
                  name: "Example item V1"
  /v2/items/{item_id}:
    get:
      summary: Retrieve an item by its ID (Version 2)
      parameters:
        - name: item_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: A successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  item_id:
                    type: integer
                  name:
                    type: string
                example:
                  item_id: 1
                  name: "Example item V2"
  • parameters 定義了從路徑中提取的參數 asset,並且該參數是必填的。

錯誤處理與回應

錯誤處理是 API 設計中非常重要的一部分,它能確保當發生錯誤時,系統能夠返回清晰的錯誤信息,方便開發者進行調試。

  • 定義回應狀態碼:在 OpenAPI 中,我們可以為每個 API 路徑設置多個回應狀態碼(如 200、400、404 等),以便開發者能準確描述 API 的行為。
  • 處理錯誤回應:OpenAPI 支持為錯誤狀況設置專門的回應格式,這對於調試和錯誤處理至關重要。
responses:
  '200':
    description: A successful response
    content:
      application/json:
        schema:
          type: object
          properties:
            message:
              type: string
        example:
          message: "Operation was successful"
  '404':
    description: Not Found - The requested item does not exist
    content:
      application/json:
        schema:
          type: object
          properties:
            error:
              type: string
        example:
          error: "Item not found"
  '400':
    description: Invalid request
    content:
      application/json:
        schema:
          type: object
          properties:
            error:
              type: string
        example:
          error: "Invalid ID supplied"
  • responses 定義了多個回應狀態碼,包括 200(成功)、400(無效請求)和 404(找不到資源)。這有助於處理不同的錯誤情況並返回相應的錯誤代碼給客戶端。
  • 我們可以根據錯誤類型,返回不同的錯誤描述,以幫助使用者了解問題所在。

安全設置與認證機制

使用 JWT(JSON Web Token)進行身份驗證是現在 Web API 常用方法之一,這允許我們安全地驗證 API 請求。

# securitySchemes 定義
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

# 將 securitySchemes 應用到路徑
paths:
  /users/me:
    get:
      security:
        - bearerAuth: []
      summary: Get current user information
      responses:
        '200':
          description: Successful response
        '401':
          description: Unauthorized - Invalid or missing token
  • securitySchemes:這部分定義了 API 的認證方式。此處我們使用了 JWT(Bearer Token) 作為認證方式。
    • type: http:這表示我們使用 HTTP 認證。
    • scheme: bearer:bearer 指的是 Bearer Token 認證方案,這是一種常見的 API 認證方式,通常與 OAuth2 或 JWT 配合使用。
    • bearerFormat: JWT:這表明我們的 Bearer Token 的具體格式是 JWT,即 JSON Web Token。JWT 是一種加密簽名的 Token 格式,常用於身份驗證。
  • /users/me:這裡定義了一個 GET 請求,用於獲取當前用戶的信息。這個路徑被設置為受保護的,僅允許經過身份驗證的請求進入。
    • security:security 定義了這個路徑需要 Bearer Token 認證才能訪問。這個配置告訴 API,當請求到達 /users/me 路徑時,API 必須檢查請求頭部中的 Bearer Token 來驗證用戶身份。
    • bearerAuth:這對應於上面在 securitySchemes 中定義的 Bearer 認證方式,告訴 API 要求請求中必須包含有效的 JWT Token 才能進行授權。

在實際運行時,JWT 認證的具體限制步驟如下:

  1. 客戶端發送請求:客戶端會在發送 API 請求時,將已經通過身份驗證的 JWT Token 放在 HTTP 請求的標頭(Header)中,格式如下:
    Authorization: Bearer <JWT Token>
    
  2. 服務器驗證 Token:API Gateway 或應用服務器接收到請求後,會檢查 Authorization 標頭中的 Bearer Token。
    • 如果 Token 是合法且有效的,請求將被授權並繼續執行。
    • 如果 Token 無效或缺失,服務器會拒絕該請求,通常返回 401 Unauthorized403 Forbidden 狀態碼。
  3. Token 的有效性:JWT Token 通常會包含加密的簽名,並攜帶用戶的身份信息、到期時間等數據。伺服器會根據這些信息來驗證 Token 是否被篡改,並確定用戶身份和授權級別。

限流、日誌與監控設置

通常需要配合 API Gateway 或其他第三方工具來實現,例如 NGINX 或 AWS API Gateway。OpenAPI 本身不包含限流的標準配置,但許多平台允許基於 OpenAPI 規範進行限流和監控設置。例如:

x-google-quota:
  metricCosts:
    requests: 1
  limitDefinitions:
    - limit: 1000  # 每日最大請求數
      interval: 1d  # 設定的時間範圍(每日)
      description: "Daily limit for each API key"

這是基於 Google Cloud 的 API Gateway 擴展,描述了如何在 OpenAPI 文件中指定每日請求限制。不同的 API Gateway 可能會有不同的限流配置。

FastAPI 與 OpenAPI 自動整合

FastAPI 框架能自動生成符合 OpenAPI 規範的 API 文檔。當你定義一個 FastAPI 應用時,它會自動創建對應的 OpenAPI 文檔,並通過 /docs 提供可視化的 Swagger UI。開發者也可以通過 /openapi.json 查看 JSON 格式的 OpenAPI 規範。

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

啟動 FastAPI 應用後,便可以通過 http://localhost:<port>/docs 看到自動生成的 Swagger UI,通過 http://localhost:<port>/openapi.json 獲取 OpenAPI 規範文檔。

這種自動生成功能使開發者不需要手動編寫 OpenAPI 文檔,並能快速查看和測試 API。


ref.


上一篇
[Day26] 防止惡意攻擊:如何通過 VPC 和 Load Balancer 保護核心服務
下一篇
[Day28] 測試驅動開發 (TDD):實現穩定性與快速迭代的開發模式
系列文
從系統設計切入,探索 GenAI 在企業中的實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言