2026-05-19 11:00:28 +00:00
|
|
|
|
# API 定義(goctl + go-doc 共用)
|
|
|
|
|
|
|
|
|
|
|
|
## 檔案
|
|
|
|
|
|
|
|
|
|
|
|
| 檔案 | 用途 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| `gateway.api` | 入口:`info()` + `import` |
|
|
|
|
|
|
| `common.api` | 共用文件型別(`APIErrorStatus`、`ErrorDetail`) |
|
2026-05-21 06:45:35 +00:00
|
|
|
|
| `auth.api` | Auth 路由(scope 28) |
|
|
|
|
|
|
| `member.api` | Member 路由(scope 29) |
|
2026-05-21 09:15:25 +00:00
|
|
|
|
| `permission.api` | Permission / RBAC 路由(scope 31) |
|
2026-05-19 11:00:28 +00:00
|
|
|
|
| `normal.api` | 路由與業務 `data` 型別 |
|
|
|
|
|
|
|
|
|
|
|
|
## 指令
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
make gen-api # 生成 handler / logic / types
|
|
|
|
|
|
make gen-doc # 生成 docs/openapi/gateway.yaml(OpenAPI 3.0)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 註解約定
|
|
|
|
|
|
|
|
|
|
|
|
- **Logic `returns`**:只寫業務 data(如 `PingData`)
|
|
|
|
|
|
- **文件 `@respdoc`**:寫實際 HTTP JSON(如 `PingOKStatus`、`APIErrorStatus`)
|
|
|
|
|
|
- **`@doc`**:單一 API 的 summary / description
|
|
|
|
|
|
- 多狀態碼用 `/* @respdoc-200 ... */` 區塊,放在 `@handler` 前
|
2026-05-19 12:56:32 +00:00
|
|
|
|
- **Request 驗證**:欄位可加 `validate:"required,email"` 等 tag;`make gen-api` 後 handler 會自動 `ValidateAll`(見 `generate/goctl/api/handler.tpl`)
|
2026-05-19 11:00:28 +00:00
|
|
|
|
|
2026-05-21 09:15:25 +00:00
|
|
|
|
## 文件分組與欄位說明(go-doc 規則)
|
|
|
|
|
|
|
|
|
|
|
|
OpenAPI 由 `generate/doc-generate`(go-doc)從 `.api` 直接讀取,下列三種寫法**必須**遵守,AI agent 在新增 / 修改 API 時請一併照做:
|
|
|
|
|
|
|
|
|
|
|
|
### 1. Swagger UI 分組(tags)
|
|
|
|
|
|
|
|
|
|
|
|
每個 `.api` 檔的 `@server (...)` 區塊**必須**帶 `tags:` 與 `summary:`,否則 endpoint 會散落在 "default" 群組。
|
|
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
|
@server (
|
|
|
|
|
|
group: permission // goctl 用:決定 handler 子目錄
|
|
|
|
|
|
prefix: /api/v1/permissions
|
|
|
|
|
|
tags: "Permission - 權限" // ← go-doc 用:Swagger UI 分組標題
|
|
|
|
|
|
summary: "Catalog / 角色 / 使用者角色 / 外部映射 / Policy"
|
|
|
|
|
|
)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
> 一個 `.api` 內可以開**多個** `@server` 區塊(相同 `group` / `prefix` 但不同 `tags:`),把同一模組再拆成子組。
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 欄位中文 description
|
|
|
|
|
|
|
|
|
|
|
|
go-doc 把欄位的 description **只認 backtick 結尾的同一行 `//` 註解**,寫在前一行不會被解析。
|
|
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
|
// ❌ 不會被當 description
|
|
|
|
|
|
RegisterReq {
|
|
|
|
|
|
// 租戶 slug
|
|
|
|
|
|
TenantSlug string `json:"tenant_slug" validate:"required"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ✅ 正確寫法(backtick 行末 //)
|
|
|
|
|
|
RegisterReq {
|
|
|
|
|
|
TenantSlug string `json:"tenant_slug" validate:"required"` // 租戶 slug(小寫英數)
|
|
|
|
|
|
Email string `json:"email" validate:"required,email"` // 電子郵件
|
|
|
|
|
|
Password string `json:"password" validate:"required,min=8,max=128"` // 密碼(8-128 字元)
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**所有 Request 型別**(命名 `*Req` / `*Query` / `*Path` 的 struct)的**每個欄位**都要加中文 description。Response / Data 型別可選。
|
|
|
|
|
|
|
|
|
|
|
|
### 3. Enum 列舉值(Swagger UI 下拉選單)
|
|
|
|
|
|
|
|
|
|
|
|
`validate:"oneof=A B C"` 是 runtime 驗證用的,**go-doc 不會解析**。要讓 Swagger UI 顯示下拉選單,必須在 tag 內加 `options=A|B|C`(管道分隔):
|
|
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
|
// ❌ 只有 validate 不會出 enum
|
|
|
|
|
|
Provider string `json:"provider" validate:"required,oneof=google"`
|
|
|
|
|
|
|
|
|
|
|
|
// ✅ 同時保留兩者:options= 給 go-doc,validate= 給 runtime
|
|
|
|
|
|
Provider string `json:"provider,options=google" validate:"required,oneof=google"`
|
|
|
|
|
|
Source string `json:"source,optional,options=manual|zitadel|ldap|scim" validate:"omitempty,oneof=manual zitadel ldap scim"`
|
|
|
|
|
|
Status string `form:"status,optional,options=open|close" validate:"omitempty,oneof=open close"`
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**規則**:只要有 `oneof=...`,就一定要在同欄位 tag 加對應 `options=...`,並把可選值也寫進行末註解。
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 修改流程
|
|
|
|
|
|
|
|
|
|
|
|
每次改 `.api` 後**必跑**:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
make gen-api # 同步 internal/types/types.go(json tag 帶 options= 給 go-zero runtime)
|
|
|
|
|
|
make gen-doc # 同步 docs/openapi/gateway.yaml(gitignore,本地驗證用)
|
|
|
|
|
|
go build ./... # 確保編譯通過
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
驗證:把 `docs/openapi/gateway.yaml` 丟進 https://editor.swagger.io 或 Swagger UI,確認分組、description、enum 都正確顯示。
|
|
|
|
|
|
|
2026-05-19 11:00:28 +00:00
|
|
|
|
## 與 runtime 對齊
|
|
|
|
|
|
|
|
|
|
|
|
Handler 使用 `response.Write` 輸出:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
2026-05-21 06:45:35 +00:00
|
|
|
|
{ "code": 102000, "message": "SUCCESS", "data": { ... } }
|
2026-05-19 11:00:28 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-21 06:45:35 +00:00
|
|
|
|
失敗時含 `error.biz_code` / `error.scope` 等欄位。Handler parse 錯誤為 Facade scope(`10101000`);各模組 logic/usecase 使用對應 scope(Auth=28、Member=29)。
|