|
||
---|---|---|
cmd/go-doc | ||
example | ||
internal | ||
.gitignore | ||
BUGFIX_REQUIRED_FIELDS.md | ||
LICENSE | ||
Makefile | ||
README.md | ||
cursor.md | ||
go.mod | ||
go.sum | ||
test_all_formats.sh | ||
test_respdoc.sh |
README.md
go-doc
go-doc 是一個獨立的命令行工具,專門用於將 go-zero .api
文件轉換為 OpenAPI 規範文檔。
原本是 go-zero 專案的一部分,現在已獨立出來,成為一個易於使用的工具,支援生成 Swagger 2.0 和 OpenAPI 3.0 兩種格式。
📑 目錄
- ✨ 特性
- 📦 安裝
- 🚀 快速開始
- 📖 API 文件格式
- 🆕 @respdoc 多狀態碼回應
- 🔧 進階功能
- 🎯 OpenAPI 3.0 vs Swagger 2.0
- 💡 使用範例
- 🧪 測試
- 📚 專案結構
- 🔄 從 go-zero 遷移
- 📝 版本記錄
- ❓ 常見問題
- 🤝 貢獻
- 📄 授權
✨ 特性
- 🚀 獨立二進制 - 無需依賴 go-zero 運行時
- 📝 雙規格支援 - 生成 Swagger 2.0 和 OpenAPI 3.0 格式
- 🎯 豐富的類型支援 - 處理結構體、陣列、映射、指針和嵌套類型
- 🏷️ 基於標籤的配置 - 支援
json
、form
、path
、header
標籤 - 📊 進階驗證 - 範圍、枚舉、預設值、範例值
- 🔐 安全定義 - 自定義身份驗證配置
- 📦 多種輸出格式 - JSON 或 YAML 輸出
- 🎨 定義引用 - 可選使用 definitions/schemas 使輸出更簡潔
- 🔄 自動轉換 - Swagger 2.0 到 OpenAPI 3.0 的無縫轉換
- 🆕 多狀態碼回應 - 使用
@respdoc
定義多個 HTTP 狀態碼 - 🆕 業務錯誤碼映射 - 將業務錯誤碼映射到不同的錯誤類型,OpenAPI 3.0 使用
oneOf
📦 安裝
從源碼編譯
git clone <your-repo>
cd go-doc
make build
編譯完成後,執行檔位於 bin/go-doc
使用 Go Install
go install github.com/danielchan-25/go-doc/cmd/go-doc@latest
🚀 快速開始
基本使用
# 生成 Swagger 2.0(預設)
go-doc -a example/example.api -d output
# 生成 OpenAPI 3.0(推薦)
go-doc -a example/example.api -d output -s openapi3.0
# 生成 YAML 格式
go-doc -a example/example.api -d output -y
# 生成 OpenAPI 3.0 YAML
go-doc -a example/example.api -d output -s openapi3.0 -y
# 自訂檔名
go-doc -a example/example.api -d output -f my-api
命令行選項
Flags:
-a, --api string API 文件路徑(必要)
-d, --dir string 輸出目錄(必要)
-f, --filename string 輸出檔名(不含副檔名)
-h, --help 顯示說明
-s, --spec-version string OpenAPI 規格版本:swagger2.0 或 openapi3.0(預設:swagger2.0)
-v, --version 顯示版本
-y, --yaml 生成 YAML 格式(預設:JSON)
使用 Makefile
# 編譯
make build
# 生成範例
make example
# 清理
make clean
# 運行測試
make test
# 查看所有命令
make help
📖 API 文件格式
基本結構
syntax = "v1"
info (
title: "My API"
description: "API documentation"
version: "v1.0.0"
host: "api.example.com"
basePath: "/v1"
)
type (
UserRequest {
Id int `json:"id,range=[1:10000]"`
Name string `json:"name"`
}
UserResponse {
Id int `json:"id"`
Name string `json:"name"`
}
)
@server (
tags: "user"
)
service MyAPI {
@handler getUser
get /user/:id (UserRequest) returns (UserResponse)
}
支援的 Info 屬性
title
- API 標題description
- API 描述version
- API 版本host
- API 主機(如 "api.example.com")basePath
- 基礎路徑(如 "/v1")schemes
- 協議(如 "http,https")consumes
- 請求內容類型produces
- 回應內容類型contactName
,contactURL
,contactEmail
- 聯絡資訊licenseName
,licenseURL
- 授權資訊useDefinitions
- 使用 Swagger definitions(true/false)wrapCodeMsg
- 將回應包裝在{code, msg, data}
結構中securityDefinitionsFromJson
- JSON 格式的安全定義
標籤選項
JSON 標籤
type Example {
// 範圍驗證
Age int `json:"age,range=[1:150]"`
// 預設值
Status string `json:"status,default=active"`
// 範例值
Email string `json:"email,example=user@example.com"`
// 枚舉值
Role string `json:"role,options=admin|user|guest"`
// 可選欄位
Phone string `json:"phone,optional"`
}
Form 標籤
type QueryRequest {
Keyword string `form:"keyword"`
Page int `form:"page,default=1"`
Size int `form:"size,range=[1:100]"`
}
Path 標籤
type PathRequest {
UserId int `path:"userId,range=[1:999999]"`
}
Header 標籤
type HeaderRequest {
Token string `header:"Authorization"`
}
🆕 @respdoc 多狀態碼回應
概述
@respdoc
註解允許您為單個 API 端點定義多個 HTTP 狀態碼的回應,並支援為同一狀態碼定義多種業務錯誤格式。
重要特性:
- ✅ 支援多個 HTTP 狀態碼(200, 201, 400, 401, 404, 500 等)
- ✅ 支援業務錯誤碼映射(如 300101, 300102 等)
- ✅ OpenAPI 3.0 使用
oneOf
表示多種錯誤格式 - ✅ Swagger 2.0 在描述中列出所有可能的錯誤
基本語法
單一回應類型
service MyAPI {
@doc (
description: "用戶查詢接口"
)
/*
@respdoc-200 (UserResponse) // 成功
@respdoc-400 (ErrorResponse) // 錯誤請求
@respdoc-401 (UnauthorizedError) // 未授權
@respdoc-500 (ServerError) // 服務器錯誤
*/
@handler getUser
get /user/:id (UserRequest) returns (UserResponse)
}
多業務錯誤碼(重點功能)⭐
service MyAPI {
@doc (
description: "創建訂單"
)
/*
@respdoc-201 (OrderResponse) // 創建成功
@respdoc-400 (
300101: (ValidationError) 參數驗證失敗
300102: (InsufficientStockError) 庫存不足
300103: (InvalidPaymentError) 支付方式無效
) // 客戶端錯誤
@respdoc-401 (UnauthorizedError) // 未授權
@respdoc-500 (ServerError) // 服務器錯誤
*/
@handler createOrder
post /order (OrderRequest) returns (OrderResponse)
}
完整範例
syntax = "v1"
info (
title: "訂單 API"
description: "訂單管理系統"
version: "v1"
host: "api.example.com"
basePath: "/v1"
useDefinitions: true
)
type (
CreateOrderReq {
ProductID string `json:"product_id"`
Quantity int `json:"quantity"`
PaymentMethod string `json:"payment_method"`
}
OrderResponse {
OrderID string `json:"order_id"`
Status string `json:"status"`
Total float64 `json:"total"`
}
ValidationError {
Code string `json:"code"`
Message string `json:"message"`
Fields []string `json:"fields"`
}
InsufficientStockError {
Code string `json:"code"`
Message string `json:"message"`
ProductID string `json:"product_id"`
Required int `json:"required"`
Available int `json:"available"`
}
InvalidPaymentError {
Code string `json:"code"`
Message string `json:"message"`
Method string `json:"method"`
}
UnauthorizedError {
Code string `json:"code"`
Message string `json:"message"`
Reason string `json:"reason"`
}
ServerError {
Code string `json:"code"`
Message string `json:"message"`
TraceID string `json:"trace_id"`
}
)
@server (
tags: "order"
)
service OrderAPI {
@doc (
description: "創建訂單"
)
/*
@respdoc-201 (OrderResponse) // 創建成功
@respdoc-400 (
300101: (ValidationError) 參數驗證失敗
300102: (InsufficientStockError) 庫存不足
300103: (InvalidPaymentError) 支付方式無效
) // 客戶端錯誤
@respdoc-401 (UnauthorizedError) // 未授權
@respdoc-500 (ServerError) // 服務器錯誤
*/
@handler createOrder
post /order (CreateOrderReq) returns (OrderResponse)
}
生成結果對比
Swagger 2.0 輸出
{
"paths": {
"/v1/order": {
"post": {
"responses": {
"201": {
"description": "// 創建成功",
"schema": {
"$ref": "#/definitions/OrderResponse"
}
},
"400": {
"description": "客戶端錯誤\n\nPossible errors:\n300101: ValidationError - 參數驗證失敗\n300102: InsufficientStockError - 庫存不足\n300103: InvalidPaymentError - 支付方式無效",
"schema": {
"$ref": "#/definitions/ValidationError"
}
}
}
}
}
}
}
OpenAPI 3.0 輸出(使用 oneOf)⭐
{
"paths": {
"/v1/order": {
"post": {
"responses": {
"201": {
"description": "// 創建成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OrderResponse"
}
}
}
},
"400": {
"description": "客戶端錯誤",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/ValidationError"
},
{
"$ref": "#/components/schemas/InsufficientStockError"
},
{
"$ref": "#/components/schemas/InvalidPaymentError"
}
]
}
}
}
}
}
}
}
}
}
優勢: OpenAPI 3.0 使用 oneOf
精確表示多種可能的錯誤類型!
🔧 進階功能
安全定義
info (
securityDefinitionsFromJson: `{
"apiKey": {
"type": "apiKey",
"name": "x-api-key",
"in": "header",
"description": "API Key Authentication"
}
}`
)
@server (
authType: apiKey
)
service MyAPI {
// 此處的路由將使用 apiKey 身份驗證
}
Code-Msg 包裝
info (
wrapCodeMsg: true
bizCodeEnumDescription: "1001-User not found<br>1002-Permission denied"
)
回應將被包裝為:
{
"code": 0,
"msg": "ok",
"data": { /* your actual response */ }
}
🎯 OpenAPI 3.0 vs Swagger 2.0
規格版本
Swagger 2.0(預設)
go-doc -a example/example.api -d output
# 或明確指定
go-doc -a example/example.api -d output -s swagger2.0
OpenAPI 3.0(推薦)
go-doc -a example/example.api -d output -s openapi3.0
主要差異
特性 | Swagger 2.0 | OpenAPI 3.0 |
---|---|---|
版本聲明 | swagger: "2.0" |
openapi: "3.0.3" |
服務器 | host , basePath , schemes |
servers 陣列 |
Schema 定義 | definitions |
components/schemas |
安全定義 | securityDefinitions |
components/securitySchemes |
請求體 | parameters[in=body] |
requestBody |
多類型回應 | ❌ 不支援 | ✅ oneOf /anyOf /allOf |
範例對比
Swagger 2.0:
{
"swagger": "2.0",
"host": "example.com",
"basePath": "/v1",
"definitions": {
"User": {...}
},
"securityDefinitions": {
"apiKey": {...}
}
}
OpenAPI 3.0:
{
"openapi": "3.0.3",
"servers": [
{"url": "http://example.com/v1"},
{"url": "https://example.com/v1"}
],
"components": {
"schemas": {
"User": {...}
},
"securitySchemes": {
"apiKey": {...}
}
}
}
💡 使用範例
場景 1:RESTful CRUD
/*
@respdoc-200 (UserResponse) // 獲取成功
@respdoc-404 (NotFoundError) // 用戶不存在
@respdoc-401 (UnauthorizedError) // 未授權
*/
@handler getUser
get /user/:id (UserIdReq) returns (UserResponse)
/*
@respdoc-201 (UserResponse) // 創建成功
@respdoc-400 (ValidationError) // 參數錯誤
@respdoc-409 (ConflictError) // 用戶已存在
*/
@handler createUser
post /user (CreateUserReq) returns (UserResponse)
/*
@respdoc-200 (UserResponse) // 更新成功
@respdoc-400 (ValidationError) // 參數錯誤
@respdoc-404 (NotFoundError) // 用戶不存在
*/
@handler updateUser
put /user/:id (UpdateUserReq) returns (UserResponse)
/*
@respdoc-204 // 刪除成功
@respdoc-404 (NotFoundError) // 用戶不存在
*/
@handler deleteUser
delete /user/:id (UserIdReq)
場景 2:複雜業務流程
/*
@respdoc-200 (PaymentResponse) // 支付成功
@respdoc-400 (
400001: (InsufficientBalanceError) 餘額不足
400002: (InvalidCardError) 無效的卡號
400003: (ExpiredCardError) 卡已過期
400004: (DailyLimitError) 超過每日限額
) // 支付失敗
@respdoc-401 (UnauthorizedError) // 未授權
@respdoc-422 (ProcessingError) // 處理中請勿重複提交
*/
@handler processPayment
post /payment (PaymentRequest) returns (PaymentResponse)
場景 3:狀態機轉換
/*
@respdoc-200 (OrderResponse) // 狀態更新成功
@respdoc-400 (
400001: (InvalidStateError) 無效的狀態轉換
400002: (OrderCancelledError) 訂單已取消
400003: (OrderCompletedError) 訂單已完成
) // 狀態轉換失敗
*/
@handler updateOrderStatus
put /order/:id/status (UpdateStatusReq) returns (OrderResponse)
🧪 測試
測試所有格式
# 測試 Swagger 2.0 和 OpenAPI 3.0
./test_all_formats.sh
# 測試 @respdoc 功能
./test_respdoc.sh
手動測試
# 生成並檢查
go-doc -a example/example_respdoc.api -d output -s openapi3.0
# 查看生成的文檔
cat output/example_respdoc.json | jq '.paths."/v1/order".post.responses'
📚 專案結構
go-doc/
├── cmd/
│ └── go-doc/ # 主程式入口
│ └── main.go
├── internal/
│ ├── swagger/ # 核心邏輯
│ │ ├── respdoc.go # @respdoc 解析
│ │ ├── response.go # 回應生成
│ │ ├── openapi3.go # OpenAPI 3.0 轉換
│ │ ├── swagger.go # Swagger 2.0 生成
│ │ ├── path.go # 路徑處理
│ │ ├── parameter.go # 參數處理
│ │ ├── definition.go # 定義處理
│ │ └── ...
│ └── util/ # 工具函數
│ ├── util.go
│ ├── stringx.go
│ └── pathx.go
├── example/
│ ├── example.api # 範例 API
│ ├── example_cn.api # 中文範例
│ ├── example_respdoc.api # @respdoc 範例
│ └── test_output/ # 生成的文檔
├── bin/ # 編譯後的執行檔
├── go.mod
├── go.sum
├── Makefile
├── README.md
├── LICENSE
├── CHANGELOG.md
├── test_all_formats.sh # 測試腳本
└── test_respdoc.sh # @respdoc 測試
🔄 從 go-zero 遷移
主要變更
1. 模組獨立
之前(go-zero plugin):
// 屬於 go-zero 內部工具
package swagger // in tools/goctl/api/plugin/swagger/
現在(standalone):
module go-doc
package swagger // in internal/swagger/
2. 依賴簡化
依賴 | 替換為 | 原因 |
---|---|---|
go-zero/tools/goctl/internal/version |
自定義版本 | 內部包不可訪問 |
go-zero/tools/goctl/util |
go-doc/internal/util |
自包含工具 |
go-zero/tools/goctl/util/stringx |
go-doc/internal/util |
自定義字串處理 |
go-zero/tools/goctl/util/pathx |
go-doc/internal/util |
自定義路徑處理 |
google.golang.org/grpc/metadata |
原生 map 處理 | 移除外部依賴 |
3. 保留的依賴
- ✅
github.com/go-openapi/spec
- Swagger 2.0 - ✅
github.com/getkin/kin-openapi
- OpenAPI 3.0 - ✅
github.com/spf13/cobra
- CLI 框架 - ✅
github.com/zeromicro/go-zero/tools/goctl/api/spec
- API 解析 - ✅
gopkg.in/yaml.v2
- YAML 支援
遷移步驟
-
安裝 go-doc
go build -o bin/go-doc ./cmd/go-doc
-
替換命令
之前:
goctl api plugin -plugin goctl-swagger="swagger -filename api.json" -api user.api -dir .
現在:
go-doc -a user.api -d . -f api
-
新功能
使用 OpenAPI 3.0:
go-doc -a user.api -d . -f api -s openapi3.0
使用 @respdoc:
/* @respdoc-200 (Response) // 成功 @respdoc-400 (Error) // 錯誤 */
📝 版本記錄
[1.2.0] - 2025-09-30
新增
- @respdoc 註解支援 - 為單個端點定義多個 HTTP 狀態碼
- 業務錯誤碼映射 - 將不同的業務錯誤碼映射到特定錯誤類型
- OpenAPI 3.0 oneOf 支援 - 使用
oneOf
表示多種可能的錯誤回應 - 測試腳本
test_respdoc.sh
- 支援解析
HandlerDoc
註釋(在@doc()
外)
增強
- 回應生成現在支援多個狀態碼(200, 201, 400, 401, 404, 500 等)
- OpenAPI 3.0 生成器為業務錯誤碼創建
oneOf
schema - Swagger 2.0 在描述中列出所有可能的錯誤
[1.1.0] - 2025-09-30
新增
- OpenAPI 3.0 支援 - 生成 Swagger 2.0 和 OpenAPI 3.0 規格
- 新增
--spec-version
(-s
) 標誌 - 自動從 Swagger 2.0 轉換到 OpenAPI 3.0
- 整合
github.com/getkin/kin-openapi
函式庫
[1.0.0] - 2025-09-30
新增
- 初始發布為獨立工具
- 從 go-zero 專案提取並獨立
- 支援將 go-zero
.api
文件轉換為 Swagger 2.0 規格 - JSON 和 YAML 輸出格式
- 使用 cobra 的命令行介面
❓ 常見問題
Q: 應該使用哪個版本?
A:
- Swagger 2.0: 如果需要與舊工具或系統相容
- OpenAPI 3.0: 推薦使用,功能更強大且為現代標準
Q: 為什麼 OpenAPI 3.0 使用 oneOf?
A: oneOf
是 OpenAPI 3.0 的標準方式來表示"多選一"的 schema。這讓 API 文檔更精確,工具(如 Swagger UI、代碼生成器)可以正確理解和處理多種可能的回應類型。
Q: Swagger 2.0 為什麼不支援 oneOf?
A: Swagger 2.0 規範不包含 oneOf
關鍵字。我們在描述中列出所有可能的錯誤,並使用第一個類型作為 schema 示例。
Q: 可以同時生成兩種格式嗎?
A: 可以!執行兩次命令即可:
go-doc -a api.api -d out -f api-v2
go-doc -a api.api -d out -f api-v3 -s openapi3.0
Q: 可以不定義業務錯誤碼嗎?
A: 可以!如果只有一種錯誤類型,直接使用單一回應格式:
@respdoc-400 (ValidationError) // 參數錯誤
Q: 如何驗證生成的文檔?
A: 可以使用以下工具:
- Swagger Editor: https://editor.swagger.io/
- Swagger UI: 本地運行或線上版本
- OpenAPI Generator: 生成客戶端/伺服器代碼來驗證
🤝 貢獻
歡迎貢獻!請隨時提交 Pull Request。
開發
# 克隆專案
git clone <your-repo>
cd go-doc
# 安裝依賴
go mod download
# 運行測試
make test
# 編譯
make build
# 運行範例
make example
📄 授權
MIT License
Copyright (c) 2025 Daniel Chan
本專案最初是 go-zero 專案 swagger 生成插件的一部分。我們感謝 go-zero 團隊的出色工作。
🎉 總結
go-doc v1.2.0 提供了強大的 API 文檔生成功能:
✅ 雙規格支援 - Swagger 2.0 和 OpenAPI 3.0
✅ 多狀態碼回應 - 使用 @respdoc 定義完整的 HTTP 回應
✅ 業務錯誤碼映射 - 支援複雜的錯誤場景
✅ OpenAPI 3.0 oneOf - 專業的多類型回應表示
✅ 完整測試 - 自動化測試腳本
✅ 詳細文檔 - 完整的使用指南
開始使用:
go-doc -a your-api.api -d docs -s openapi3.0
查看範例:
- 基本範例:
example/example.api
- @respdoc 範例:
example/example_respdoc.api
- 測試腳本:
./test_respdoc.sh
🌟 如果這個專案對您有幫助,請給個 Star!