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

533 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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 規格
```