885 lines
21 KiB
Markdown
885 lines
21 KiB
Markdown
# go-doc
|
||
|
||
[](https://go.dev/)
|
||
[](LICENSE)
|
||
[](CHANGELOG.md)
|
||
|
||
**go-doc** 是一個獨立的命令行工具,專門用於將 [go-zero](https://github.com/zeromicro/go-zero) `.api` 文件轉換為 OpenAPI 規範文檔。
|
||
|
||
原本是 go-zero 專案的一部分,現在已獨立出來,成為一個易於使用的工具,支援生成 **Swagger 2.0** 和 **OpenAPI 3.0** 兩種格式。
|
||
|
||
---
|
||
|
||
## 📑 目錄
|
||
|
||
- [✨ 特性](#-特性)
|
||
- [📦 安裝](#-安裝)
|
||
- [🚀 快速開始](#-快速開始)
|
||
- [📖 API 文件格式](#-api-文件格式)
|
||
- [🆕 @respdoc 多狀態碼回應](#-respdoc-多狀態碼回應)
|
||
- [🔧 進階功能](#-進階功能)
|
||
- [🎯 OpenAPI 3.0 vs Swagger 2.0](#-openapi-30-vs-swagger-20)
|
||
- [💡 使用範例](#-使用範例)
|
||
- [🧪 測試](#-測試)
|
||
- [📚 專案結構](#-專案結構)
|
||
- [🔄 從 go-zero 遷移](#-從-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`
|
||
|
||
---
|
||
|
||
## 📦 安裝
|
||
|
||
### 從源碼編譯
|
||
|
||
```bash
|
||
git clone <your-repo>
|
||
cd go-doc
|
||
make build
|
||
```
|
||
|
||
編譯完成後,執行檔位於 `bin/go-doc`
|
||
|
||
### 使用 Go Install
|
||
|
||
```bash
|
||
go install github.com/danielchan-25/go-doc/cmd/go-doc@latest
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 快速開始
|
||
|
||
### 基本使用
|
||
|
||
```bash
|
||
# 生成 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
|
||
|
||
```bash
|
||
# 編譯
|
||
make build
|
||
|
||
# 生成範例
|
||
make example
|
||
|
||
# 清理
|
||
make clean
|
||
|
||
# 運行測試
|
||
make test
|
||
|
||
# 查看所有命令
|
||
make help
|
||
```
|
||
|
||
---
|
||
|
||
## 📖 API 文件格式
|
||
|
||
### 基本結構
|
||
|
||
```go
|
||
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 標籤
|
||
|
||
```go
|
||
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 標籤
|
||
|
||
```go
|
||
type QueryRequest {
|
||
Keyword string `form:"keyword"`
|
||
Page int `form:"page,default=1"`
|
||
Size int `form:"size,range=[1:100]"`
|
||
}
|
||
```
|
||
|
||
#### Path 標籤
|
||
|
||
```go
|
||
type PathRequest {
|
||
UserId int `path:"userId,range=[1:999999]"`
|
||
}
|
||
```
|
||
|
||
#### Header 標籤
|
||
|
||
```go
|
||
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 在描述中列出所有可能的錯誤
|
||
|
||
### 基本語法
|
||
|
||
#### 單一回應類型
|
||
|
||
```go
|
||
service MyAPI {
|
||
@doc (
|
||
description: "用戶查詢接口"
|
||
)
|
||
/*
|
||
@respdoc-200 (UserResponse) // 成功
|
||
@respdoc-400 (ErrorResponse) // 錯誤請求
|
||
@respdoc-401 (UnauthorizedError) // 未授權
|
||
@respdoc-500 (ServerError) // 服務器錯誤
|
||
*/
|
||
@handler getUser
|
||
get /user/:id (UserRequest) returns (UserResponse)
|
||
}
|
||
```
|
||
|
||
#### 多業務錯誤碼(重點功能)⭐
|
||
|
||
```go
|
||
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)
|
||
}
|
||
```
|
||
|
||
### 完整範例
|
||
|
||
```go
|
||
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 輸出
|
||
|
||
```json
|
||
{
|
||
"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)⭐
|
||
|
||
```json
|
||
{
|
||
"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` 精確表示多種可能的錯誤類型!
|
||
|
||
---
|
||
|
||
## 🔧 進階功能
|
||
|
||
### 安全定義
|
||
|
||
```go
|
||
info (
|
||
securityDefinitionsFromJson: `{
|
||
"apiKey": {
|
||
"type": "apiKey",
|
||
"name": "x-api-key",
|
||
"in": "header",
|
||
"description": "API Key Authentication"
|
||
}
|
||
}`
|
||
)
|
||
|
||
@server (
|
||
authType: apiKey
|
||
)
|
||
service MyAPI {
|
||
// 此處的路由將使用 apiKey 身份驗證
|
||
}
|
||
```
|
||
|
||
### Code-Msg 包裝
|
||
|
||
```go
|
||
info (
|
||
wrapCodeMsg: true
|
||
bizCodeEnumDescription: "1001-User not found<br>1002-Permission denied"
|
||
)
|
||
```
|
||
|
||
回應將被包裝為:
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"msg": "ok",
|
||
"data": { /* your actual response */ }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 OpenAPI 3.0 vs Swagger 2.0
|
||
|
||
### 規格版本
|
||
|
||
#### Swagger 2.0(預設)
|
||
```bash
|
||
go-doc -a example/example.api -d output
|
||
# 或明確指定
|
||
go-doc -a example/example.api -d output -s swagger2.0
|
||
```
|
||
|
||
#### OpenAPI 3.0(推薦)
|
||
```bash
|
||
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:**
|
||
```json
|
||
{
|
||
"swagger": "2.0",
|
||
"host": "example.com",
|
||
"basePath": "/v1",
|
||
"definitions": {
|
||
"User": {...}
|
||
},
|
||
"securityDefinitions": {
|
||
"apiKey": {...}
|
||
}
|
||
}
|
||
```
|
||
|
||
**OpenAPI 3.0:**
|
||
```json
|
||
{
|
||
"openapi": "3.0.3",
|
||
"servers": [
|
||
{"url": "http://example.com/v1"},
|
||
{"url": "https://example.com/v1"}
|
||
],
|
||
"components": {
|
||
"schemas": {
|
||
"User": {...}
|
||
},
|
||
"securitySchemes": {
|
||
"apiKey": {...}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 💡 使用範例
|
||
|
||
### 場景 1:RESTful CRUD
|
||
|
||
```go
|
||
/*
|
||
@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:複雜業務流程
|
||
|
||
```go
|
||
/*
|
||
@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:狀態機轉換
|
||
|
||
```go
|
||
/*
|
||
@respdoc-200 (OrderResponse) // 狀態更新成功
|
||
@respdoc-400 (
|
||
400001: (InvalidStateError) 無效的狀態轉換
|
||
400002: (OrderCancelledError) 訂單已取消
|
||
400003: (OrderCompletedError) 訂單已完成
|
||
) // 狀態轉換失敗
|
||
*/
|
||
@handler updateOrderStatus
|
||
put /order/:id/status (UpdateStatusReq) returns (OrderResponse)
|
||
```
|
||
|
||
---
|
||
|
||
## 🧪 測試
|
||
|
||
### 測試所有格式
|
||
|
||
```bash
|
||
# 測試 Swagger 2.0 和 OpenAPI 3.0
|
||
./test_all_formats.sh
|
||
|
||
# 測試 @respdoc 功能
|
||
./test_respdoc.sh
|
||
```
|
||
|
||
### 手動測試
|
||
|
||
```bash
|
||
# 生成並檢查
|
||
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
|
||
// 屬於 go-zero 內部工具
|
||
package swagger // in tools/goctl/api/plugin/swagger/
|
||
```
|
||
|
||
**現在(standalone):**
|
||
```go
|
||
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 支援
|
||
|
||
### 遷移步驟
|
||
|
||
1. **安裝 go-doc**
|
||
```bash
|
||
go build -o bin/go-doc ./cmd/go-doc
|
||
```
|
||
|
||
2. **替換命令**
|
||
|
||
**之前:**
|
||
```bash
|
||
goctl api plugin -plugin goctl-swagger="swagger -filename api.json" -api user.api -dir .
|
||
```
|
||
|
||
**現在:**
|
||
```bash
|
||
go-doc -a user.api -d . -f api
|
||
```
|
||
|
||
3. **新功能**
|
||
|
||
使用 OpenAPI 3.0:
|
||
```bash
|
||
go-doc -a user.api -d . -f api -s openapi3.0
|
||
```
|
||
|
||
使用 @respdoc:
|
||
```go
|
||
/*
|
||
@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:** 可以!執行兩次命令即可:
|
||
```bash
|
||
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:** 可以!如果只有一種錯誤類型,直接使用單一回應格式:
|
||
```go
|
||
@respdoc-400 (ValidationError) // 參數錯誤
|
||
```
|
||
|
||
### Q: 如何驗證生成的文檔?
|
||
**A:** 可以使用以下工具:
|
||
- **Swagger Editor**: https://editor.swagger.io/
|
||
- **Swagger UI**: 本地運行或線上版本
|
||
- **OpenAPI Generator**: 生成客戶端/伺服器代碼來驗證
|
||
|
||
---
|
||
|
||
## 🤝 貢獻
|
||
|
||
歡迎貢獻!請隨時提交 Pull Request。
|
||
|
||
### 開發
|
||
|
||
```bash
|
||
# 克隆專案
|
||
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](https://github.com/zeromicro/go-zero) 專案 swagger 生成插件的一部分。我們感謝 go-zero 團隊的出色工作。
|
||
|
||
---
|
||
|
||
## 🎉 總結
|
||
|
||
**go-doc v1.2.0** 提供了強大的 API 文檔生成功能:
|
||
|
||
✅ **雙規格支援** - Swagger 2.0 和 OpenAPI 3.0
|
||
✅ **多狀態碼回應** - 使用 @respdoc 定義完整的 HTTP 回應
|
||
✅ **業務錯誤碼映射** - 支援複雜的錯誤場景
|
||
✅ **OpenAPI 3.0 oneOf** - 專業的多類型回應表示
|
||
✅ **完整測試** - 自動化測試腳本
|
||
✅ **詳細文檔** - 完整的使用指南
|
||
|
||
開始使用:
|
||
```bash
|
||
go-doc -a your-api.api -d docs -s openapi3.0
|
||
```
|
||
|
||
查看範例:
|
||
- 基本範例:`example/example.api`
|
||
- @respdoc 範例:`example/example_respdoc.api`
|
||
- 測試腳本:`./test_respdoc.sh`
|
||
|
||
---
|
||
|
||
**🌟 如果這個專案對您有幫助,請給個 Star!** |