跳至主要内容

API 規格文檔目錄

本目錄包含所有 REST API 端點的詳細規格。

API 文檔列表

領域文檔狀態
認證authentication.md✅ 已完成
多因素認證mfa.md🔵 設計中
訂單管理orders.md✅ 已完成
客戶管理customers.md✅ 已完成
產品管理products.md✅ 已完成
支付管理payments.md🟡 Phase 2

API 設計原則

1. RESTful 風格

  • 使用名詞表示資源(不使用動詞)
  • 使用 HTTP 方法表達操作意圖
  • 遵循 HTTP 狀態碼語義

2. HTTP 方法規範

方法用途語意冪等性範例
GET讀取資源獲取資源,不改變狀態✅ 冪等GET /orders/123
POST創建資源創建新資源❌ 非冪等POST /orders
PUT完整替換替換整個資源,需傳所有欄位✅ 冪等PUT /orders/123
PATCH部分更新只更新指定欄位✅ 冪等PATCH /orders/123/status
DELETE刪除資源刪除指定資源✅ 冪等DELETE /orders/123

PUT vs PATCH 使用原則

# PUT - 完整替換(需要傳送所有欄位)
PUT /api/v1/orders/123
Content-Type: application/json

{
"customerId": "cust-1",
"items": [...],
"deliveryDate": "2025-12-21",
"deliveryAddress": "...",
"status": "PENDING"
// ... 必須包含所有欄位
}

# PATCH - 部分更新(只傳送要更新的欄位)
PATCH /api/v1/orders/123/status
Content-Type: application/json

{
"status": "CONFIRMED"
}

使用指引

  • 狀態更新:使用 PATCH(只更新狀態欄位)
  • 單一欄位更新:使用 PATCH(如更新備註、地址)
  • 完整表單提交:使用 PUT(替換整個資源)
  • 避免:用 PUT 做部分更新(容易覆蓋未傳送的欄位)

3. 版本控制

  • API 路徑包含版本號:/api/v1/
  • 未來重大變更時遞增版本號

4. 多租戶隔離

  • 所有請求需包含 JWT Token(含 tenantId
  • 後端自動過濾資源(確保 Tenant 隔離)

5. 統一響應格式

成功響應(單一資源)

{
"id": "resource-001",
"name": "資源名稱",
...
}

成功響應(列表資源)

Response Body:

[
{ "id": "resource-001", ... },
{ "id": "resource-002", ... }
]

Response Headers:

X-Total-Count: 100
X-Page: 1
X-Per-Page: 20
Link: </api/v1/resources?page=2>; rel="next", </api/v1/resources?page=5>; rel="last"

錯誤響應

{
"error": "ERROR_CODE",
"message": "錯誤說明",
"field": "fieldName",
"timestamp": "2025-10-31T10:30:00Z"
}

6. 分頁設計規範

所有列表 API 必須使用 HTTP Headers 返回分頁資訊(不在 Response Body 中)

Request Parameters

參數類型必填說明預設值
pageintegerNo頁碼(從 1 開始)1
limitintegerNo每頁數量(10, 20, 50, 100)20
sortstringNo排序(如 createdAt:desccreatedAt:desc

Response Headers

Header類型說明範例
X-Total-Countinteger總筆數100
X-Pageinteger當前頁碼1
X-Per-Pageinteger每頁筆數20
Linkstring分頁導航連結(RFC 5988)<...>; rel="next"
Link: </api/v1/resources?page=2&limit=20>; rel="next",
</api/v1/resources?page=5&limit=20>; rel="last",
</api/v1/resources?page=1&limit=20>; rel="first"

rel 值說明:

  • first: 第一頁
  • prev: 上一頁(僅當 page > 1 時)
  • next: 下一頁(僅當有下一頁時)
  • last: 最後一頁

範例

GET /api/v1/orders?page=2&limit=20&sort=createdAt:desc
Authorization: Bearer {token}

HTTP/1.1 200 OK
X-Total-Count: 100
X-Page: 2
X-Per-Page: 20
Link: </api/v1/orders?page=3&limit=20>; rel="next",
</api/v1/orders?page=5&limit=20>; rel="last",
</api/v1/orders?page=1&limit=20>; rel="first",
</api/v1/orders?page=1&limit=20>; rel="prev"
Content-Type: application/json

[
{ "id": "order-021", ... },
{ "id": "order-022", ... },
...
]

設計理由:

  1. ✅ 符合 RESTful 最佳實踐(分離元數據與資料)
  2. ✅ Response Body 更簡潔(直接返回陣列)
  3. ✅ 支援 HTTP 快取(Headers 可被 CDN/Proxy 快取)
  4. ✅ 符合 RFC 5988 Link Header 標準

API 文檔模板

# {領域} API

## 概述
(簡述此 API 的用途與適用場景)

---

## 端點列表

| 方法 | 路徑 | 說明 | 權限 |
|------|------|------|------|
| GET | /api/v1/{resource} | 列出資源 | ROLE_XXX |
| GET | /api/v1/{resource}/:id | 獲取單一資源 | ROLE_XXX |
| POST | /api/v1/{resource} | 創建資源 | ROLE_XXX |
| PUT | /api/v1/{resource}/:id | 更新資源 | ROLE_XXX |
| DELETE | /api/v1/{resource}/:id | 刪除資源 | ROLE_XXX |

---

## 端點詳細規格

### GET /api/v1/{resource}

**描述**: 列出所有資源(支援分頁、過濾、排序)

**權限**: `ROLE_STAFF` 或更高

**Query Parameters**:

| 參數 | 類型 | 必填 | 說明 | 預設值 |
|------|------|------|------|--------|
| page | integer | No | 頁碼(從 1 開始) | 1 |
| size | integer | No | 每頁數量 | 20 |
| sort | string | No | 排序欄位(如 createdAt:desc) | createdAt:desc |
| status | string | No | 過濾狀態 | - |

**請求範例**:
\`\`\`http
GET /api/v1/resources?page=1&limit=20&status=active
Authorization: Bearer {token}
\`\`\`

**響應範例** (200 OK):

**Headers**:
\`\`\`
X-Total-Count: 100
X-Page: 1
X-Per-Page: 20
Link: </api/v1/resources?page=2&limit=20>; rel="next", </api/v1/resources?page=5&limit=20>; rel="last"
\`\`\`

**Body**:
\`\`\`json
[
{
"id": "resource-001",
"name": "資源名稱",
...
},
{
"id": "resource-002",
"name": "資源名稱 2",
...
}
]
\`\`\`

**錯誤響應**:
- `401 Unauthorized`: Token 無效或過期
- `403 Forbidden`: 權限不足

---

### POST /api/v1/{resource}

**描述**: 創建新資源

**權限**: `ROLE_STAFF` 或更高

**Request Body**:
\`\`\`json
{
"field1": "value1",
"field2": "value2",
...
}
\`\`\`

**欄位說明**:

| 欄位 | 類型 | 必填 | 說明 | 驗證規則 |
|------|------|------|------|----------|
| field1 | string | Yes | 欄位說明 | 最少 3 字元 |
| field2 | integer | No | 欄位說明 | 範圍 1-100 |

**請求範例**:
\`\`\`http
POST /api/v1/resources
Authorization: Bearer {token}
Content-Type: application/json

{
"field1": "value1",
"field2": 50
}
\`\`\`

**響應範例** (201 Created):
\`\`\`json
{
"id": "resource-001",
"field1": "value1",
"field2": 50,
"createdAt": "2025-10-31T10:30:00Z",
"createdBy": "user-001"
}
\`\`\`

**錯誤響應**:
- `400 Bad Request`: 缺少必填欄位或驗證失敗
- `401 Unauthorized`: Token 無效
- `403 Forbidden`: 權限不足

---

## 通用錯誤碼

| 錯誤碼 | HTTP 狀態 | 說明 |
|--------|-----------|------|
| VALIDATION_ERROR | 400 | 輸入驗證失敗 |
| UNAUTHORIZED | 401 | 未認證或 Token 無效 |
| FORBIDDEN | 403 | 權限不足 |
| RESOURCE_NOT_FOUND | 404 | 資源不存在 |
| CONFLICT | 409 | 資源衝突(如重複創建) |
| INTERNAL_ERROR | 500 | 伺服器內部錯誤 |

---

## 多租戶隔離

所有 API 自動執行 Tenant 隔離:

1. 從 JWT Token 提取 `tenantId`
2. 自動過濾查詢結果(僅返回當前 Tenant 的數據)
3. 創建資源時自動附加 `tenantId`
4. 跨 Tenant 訪問會返回 `404 Not Found`(而非 `403`,避免資訊洩漏)

---

## 速率限制

- 每個 IP 每分鐘最多 100 個請求
- 超過限制返回 `429 Too Many Requests`

---

## 參考資源

- [HTTP 狀態碼](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
- [REST API 設計指南](https://restfulapi.net/)

最後更新: 2025-10-31