opencode-workflow/design-idea/translate/skills/be-api-design/SKILL.md

533 lines
12 KiB
Markdown
Raw Normal View History

2026-04-08 23:53:15 +00:00
---
name: be-api-design
description: "Backend Agent 使用此技能設計 API 規格。根據 PRD 產出 OpenAPI 3.0 規格,包含端點、請求/回應結構、錯誤處理。觸發時機PRD 通過後Stage 4。"
---
# /be-api-design — API 設計
Backend Agent 使用此技能設計 API 規格。
## 職責
1. 分析 PRD 中的功能性需求
2. 使用 `design-an-interface` 探索多種 API 設計方案
3. 設計 RESTful API 端點
4. 定義請求/回應 schema
5. 設計錯誤處理機制
6. 產出 OpenAPI 3.0 規格
## 輸入
- PRD 文件 (`docs/prd/{date}-{feature}.md`)
- 現有 API 風格 (專案中現有的 API 規格)
- 資料模型上下文
## 輸出
- API 規格文件: `docs/api/{date}-{feature}.yaml` (OpenAPI 3.0)
## 流程
```
讀取 PRD
識別資源與操作
呼叫 design-an-interface 探索 2-3 種設計方案
選定最佳方案
定義 OpenAPI Schema
設計錯誤處理
安全性審查
產出 OpenAPI 文件
```
### 步驟說明
**1. 讀取 PRD**
從 PRD 中提取所有功能性需求,識別:
- 資源(名詞):使用者、訂單、商品等
- 操作(動詞):建立、讀取、更新、刪除等
- 關係:資源之間的關聯(一對多、多對多)
- 非功能性需求:分頁、速率限制、認證等
**2. 識別資源與操作**
將功能性需求映射為 RESTful 資源:
- 每個名詞 → 潛在資源
- 每個動詞 → HTTP method
- 每個關係 → 巢狀資源或獨立端點
**3. 呼叫 design-an-interface**
使用 `design-an-interface` 技能,產生 2-3 種截然不同的 API 設計方案:
- 方案 A最小化方法數每個資源 1-3 個端點)
- 方案 B最大化彈性支援多種使用情境
- 方案 C最佳化最常見的操作
比較各方案的優劣,選定最佳設計。
**4. 定義 OpenAPI Schema**
使用下方模板產出完整的 OpenAPI 3.0 規格。
**5. 安全性審查**
確認所有端點都有適當的認證機制和權限控制。
**6. 產出文件**
儲存至 `docs/api/{date}-{feature}.yaml`
## 設計原則
### RESTful 設計
```yaml
資源導向:
- URL 代表資源,而非動作
- HTTP 方法代表動作
範例:
GET /api/v1/users # 列出使用者
GET /api/v1/users/{id} # 取得特定使用者
POST /api/v1/users # 建立使用者
PUT /api/v1/users/{id} # 完整更新
PATCH /api/v1/users/{id} # 部分更新
DELETE /api/v1/users/{id} # 刪除使用者
巢狀資源:
GET /api/v1/users/{id}/orders # 取得使用者的訂單
POST /api/v1/users/{id}/orders # 為使用者建立訂單
```
### HTTP 狀態碼
```yaml
成功:
200: OK # GET, PUT, PATCH, DELETE 成功
201: Created # POST 成功建立資源
204: No Content # DELETE 成功,無回應內容
客戶端錯誤:
400: Bad Request # 請求格式錯誤
401: Unauthorized # 未認證
403: Forbidden # 無權限
404: Not Found # 資源不存在
409: Conflict # 資源衝突 (如重複)
422: Unprocessable Entity # 驗證錯誤
429: Too Many Requests # 速率限制
伺服器錯誤:
500: Internal Server Error # 伺服器內部錯誤
502: Bad Gateway # 上游服務錯誤
503: Service Unavailable # 服務暫時不可用
```
### 回應格式
```yaml
成功回應:
type: object
properties:
data:
type: object
meta:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
total_pages:
type: integer
錯誤回應:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
```
## OpenAPI 3.0 模板
```yaml
openapi: 3.0.3
info:
title: {API 名稱}
version: 1.0.0
description: |
{描述}
Related PRD: {PRD 連結}
servers:
- url: https://api.example.com/v1
description: Production
- url: https://staging-api.example.com/v1
description: Staging
paths:
/users:
get:
summary: 列出使用者
tags:
- Users
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: limit
in: query
schema:
type: integer
default: 20
maximum: 100
- name: search
in: query
schema:
type: string
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserListResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalError'
post:
summary: 建立使用者
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: 建立成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'400':
$ref: '#/components/responses/BadRequest'
'422':
$ref: '#/components/responses/ValidationError'
/users/{id}:
parameters:
- name: id
in: path
required: true
schema:
type: string
get:
summary: 取得使用者
tags:
- Users
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
put:
summary: 完整更新使用者
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUserRequest'
responses:
'200':
description: 更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
patch:
summary: 部分更新使用者
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PatchUserRequest'
responses:
'200':
description: 更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
delete:
summary: 刪除使用者
tags:
- Users
responses:
'204':
description: 刪除成功
'404':
$ref: '#/components/responses/NotFound'
components:
schemas:
User:
type: object
properties:
id:
type: string
example: "usr_123456"
email:
type: string
format: email
example: "user@example.com"
name:
type: string
example: "John Doe"
status:
type: string
enum: [active, inactive, suspended]
example: "active"
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
required:
- id
- email
- name
- status
- created_at
- updated_at
CreateUserRequest:
type: object
properties:
email:
type: string
format: email
password:
type: string
minLength: 8
name:
type: string
minLength: 1
maxLength: 100
required:
- email
- password
- name
UpdateUserRequest:
type: object
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
maxLength: 100
status:
type: string
enum: [active, inactive]
PatchUserRequest:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 100
status:
type: string
enum: [active, inactive]
UserResponse:
type: object
properties:
data:
$ref: '#/components/schemas/User'
UserListResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
meta:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
total_pages:
type: integer
Error:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
responses:
BadRequest:
description: 請求格式錯誤
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: 未認證
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: 資源不存在
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
ValidationError:
description: 驗證錯誤
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InternalError:
description: 伺服器內部錯誤
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
```
## 設計檢查清單
### 安全性
- [ ] 所有端點都有適當的認證機制
- [ ] 輸入驗證完整
- [ ] 速率限制設計
- [ ] CORS 配置
### 效能
- [ ] 分頁支援
- [ ] 快取策略
- [ ] 批次操作支援
### 可靠性
- [ ] 錯誤回應格式統一
- [ ] 重試機制建議
- [ ] 冪等性設計
### 一致性
- [ ] 命名規範一致 (資源用名詞複數)
- [ ] 回應格式一致 (data/meta/error 結構)
- [ ] 篩選/排序/分頁參數一致
## 相依技能
- **前置**: `write-a-prd` (PRD 通過後)
- **輔助**: `design-an-interface` (探索多種設計方案)
- **後續**: `dba-schema` (DB Schema 設計)
- **退回**: 可退回 `write-a-prd` 修改需求
## 退回機制
```
Design Review 退回 API 設計
修改 OpenAPI 規格
重新提交 (或重新呼叫 design-an-interface)
DBA Agent 發現 Schema 衝突
協商調整 domain model 或 API 回應格式
更新 OpenAPI 規格
```