优化swagger文档生成

This commit is contained in:
白茶清欢 2025-02-07 21:27:33 +08:00
parent 28419222a7
commit 1d7b81cffa
6 changed files with 72 additions and 64 deletions

View File

@ -84,8 +84,8 @@ type SwaggerDefinitionProperty struct {
Type string `json:"type"` // 类型
Items *SwaggerDefinitionPropertyItem `json:"items,omitempty"` // 引用类型中的引用(数组)
AllOf []map[string]string `json:"allOf,omitempty"` // 引用类型中的引用(对象)
XGoName string `json:"x-go-name"` // go字段名称
XGoPackage string `json:"x-go-package"` // go 包路径
XGoName string `json:"x-go-name,omitempty"` // go字段名称
XGoPackage string `json:"x-go-package,omitempty"` // go 包路径
}
// SwaggerDefinitionPropertyItem 属性item兴义
@ -107,9 +107,9 @@ type Swagger struct {
BasePath string `json:"basePath"` // 基础path
Info Info `json:"info"` // 文档描述信息
Paths map[string]map[string]*SwaggerPathConfig `json:"paths"` // 接口列表 : 接口 => 请求方法 => 请求配置
Definitions map[string]*SwaggerDefinition `json:"definitions"` // 数据定义
Responses map[string]*SwaggerPathConfigResponse `json:"responses"` // 响应结构列表
SecurityDefinitions map[string]*SwaggerPathConfigParameter `json:"securityDefinitions"` // 安全选项
Definitions map[string]*SwaggerDefinition `json:"definitions,omitempty"` // 数据定义
Responses map[string]*SwaggerPathConfigResponse `json:"responses,omitempty"` // 响应结构列表
SecurityDefinitions map[string]*SwaggerPathConfigParameter `json:"securityDefinitions,omitempty"` // 安全选项
}
// SwaggerInput ...

8
go.mod
View File

@ -3,20 +3,18 @@ module git.zhangdeman.cn/gateway/api-doc
go 1.22.2
require (
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241225030757-c00354fe4630
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250207132005-330777d80591
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240422034417-8c922be06d95
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9
github.com/tidwall/gjson v1.18.0
)
require (
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 // indirect
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mozillazg/go-pinyin v0.20.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect

26
go.sum
View File

@ -1,15 +1,17 @@
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241125100843-b1b286c7a701 h1:G+lGQmjMOBWGspZfijZvenGUAKpjBBrkRXLg3+GZp0U=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241125100843-b1b286c7a701/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241225030757-c00354fe4630 h1:KTp27pHr25X5khTi4B/OdFv/34UWkq6sgDfz5aBtj74=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241225030757-c00354fe4630/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 h1:I/wOsRpCSRkU9vo1u703slQsmK0wnNeZzsWQOGtIAG0=
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250207125648-b75d2ec7f3c1 h1:qWqq6dWW2eIpaXvLBUjTrbOzX1xrSw/nswz2ZL7a8Zw=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250207125648-b75d2ec7f3c1/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250207130030-67b5d5cc6121 h1:48wtD5FTfQ6AiHWrFHg/IaCxzNWYRbuGlENWDhn0Fbw=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250207130030-67b5d5cc6121/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250207132005-330777d80591 h1:P58+JwVhycrAFqE2Eq25N9y5lDokYBUz+oLxCKk44BE=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250207132005-330777d80591/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y=
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI=
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7GG14qgXKB4MEXQFOe7/UYebsqMfPaSX80TcPdOosI=
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs=
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240422034417-8c922be06d95 h1:3lO4ap9p7kEA+4yL5ojG9mAWsz5sY28Nu2tSzAZEehw=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240422034417-8c922be06d95/go.mod h1:Fo4XOiZPua4E4/Qzy3ZYS5zyd15bS/lsb3t6S6PQFGY=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9 h1:yF770WIDNwyiKL0nwmBGmjZvNCLXtHQL4xJyffPjTMU=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9/go.mod h1:I76wxEsWq7KnMQ84elpwTjEqq4I49QFw60tp5h7iGBs=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
@ -18,18 +20,14 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ=
github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=

View File

@ -62,7 +62,9 @@ func formatDocConfig(docConfig *define.SwaggerInput) {
itemPath.Summary = strings.TrimSpace(itemPath.Summary)
itemPath.Summary = wrapper.TernaryOperator.String(len(itemPath.Summary) == 0, wrapper.String("接口 : "+itemPath.Uri), wrapper.String(itemPath.Summary)).Value()
// 默认标签
itemPath.TagList = wrapper.TernaryOperator.Array(len(itemPath.TagList) == 0, wrapper.ArrayType([]string{"未分组"}), wrapper.ArrayType(itemPath.TagList)).ToStringSlice()
if len(itemPath.TagList) == 0 {
itemPath.TagList = []string{"未分组"}
}
for _, itemParam := range itemPath.ParameterList {
// 填充默认参数位置
itemParam.In = strings.TrimSpace(itemParam.In)
@ -148,10 +150,12 @@ func generatePathParameterConfig(swaggerInfo *define.Swagger, pathConfig *define
Name: realParamName,
In: itemParamInput.In,
Required: itemParamInput.Required,
Schema: map[string]string{},
Schema: &define.SwaggerPathConfigParameterSchema{
Ref: "",
},
}
if len(parentPath) > 0 {
generateParam.Schema[consts.SwaggerRefKey] = getRefValue(pathConfig.Uri + ".jsonBody")
generateParam.Schema.Ref = getRefValue(pathConfig.Uri + ".jsonBody")
generateParam.Type = ""
}
swaggerInfo.Paths[pathConfig.Uri][pathConfig.Method].Parameters = append(swaggerInfo.Paths[pathConfig.Uri][pathConfig.Method].Parameters, generateParam)
@ -225,8 +229,10 @@ func generateParameterDefinitions(swaggerInfo *define.Swagger, uri string, paren
swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]] = &define.SwaggerDefinitionProperty{
Description: paramConfig.Description,
Type: consts.SwaggerDataTypeArray,
Items: map[string]string{
consts.SwaggerTypeKey: util.GetSwaggerType(paramConfig.Type),
Items: &define.SwaggerDefinitionPropertyItem{
Type: util.GetSwaggerType(paramConfig.Type),
Ref: "",
Enum: nil,
},
}
} else {
@ -266,8 +272,10 @@ func generateParameterDefinitions(swaggerInfo *define.Swagger, uri string, paren
swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]] = &define.SwaggerDefinitionProperty{
Description: "参数描述",
Type: consts.SwaggerDataTypeArray,
Items: map[string]string{
consts.SwaggerRefKey: getRefValue(nextParentPath),
Items: &define.SwaggerDefinitionPropertyItem{
Type: "",
Ref: getRefValue(nextParentPath),
Enum: nil,
},
}
generateParameterDefinitions(swaggerInfo, uri, nextParentPath, strings.Join(subPathArr[2:], "."), paramConfig)
@ -285,8 +293,10 @@ func generateParameterDefinitions(swaggerInfo *define.Swagger, uri string, paren
}}
} else if itemSwaggerDefinition.Type == consts.SwaggerDataTypeArray {
itemSwaggerDefinition.Description = "数组描述"
itemSwaggerDefinition.Items = map[string]string{
consts.SwaggerRefKey: getRefValue(parentPath + "." + subPathArr[0] + ".item"),
itemSwaggerDefinition.Items = &define.SwaggerDefinitionPropertyItem{
Type: "",
Ref: getRefValue(parentPath + "." + subPathArr[0] + ".item"),
Enum: nil,
}
}
swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]] = itemSwaggerDefinition
@ -308,8 +318,10 @@ func handleOneLevelSubPath(swaggerInfo *define.Swagger, uri string, parentPath s
swaggerInfo.Definitions[parentPath].Properties[subPath] = &define.SwaggerDefinitionProperty{
Description: paramConfig.Description,
Type: consts.SwaggerDataTypeArray,
Items: map[string]string{
consts.SwaggerTypeKey: util.GetSwaggerType(strings.TrimSuffix(paramConfig.Type, "[]")),
Items: &define.SwaggerDefinitionPropertyItem{
Type: util.GetSwaggerType(strings.TrimSuffix(paramConfig.Type, "[]")),
Ref: "",
Enum: nil,
},
}
return

View File

@ -46,7 +46,7 @@ func TestGenerate(t *testing.T) {
TagList: []string{"测试接口生成"},
ParameterList: []*define.SwaggerParameterInput{
&define.SwaggerParameterInput{
Type: consts.DataTypeString,
Type: consts.DataTypeString.String(),
Description: "姓名",
Name: "name",
In: "body",
@ -54,7 +54,7 @@ func TestGenerate(t *testing.T) {
EnumList: []interface{}{"zhang", "de", "man"},
},
&define.SwaggerParameterInput{
Type: consts.DataTypeString,
Type: consts.DataTypeString.String(),
Description: "性别",
Name: "person.sex",
In: "body",
@ -62,7 +62,7 @@ func TestGenerate(t *testing.T) {
EnumList: []interface{}{"man", "woman", "other"},
},
&define.SwaggerParameterInput{
Type: consts.DataTypeString,
Type: consts.DataTypeString.String(),
Description: "性别",
Name: "person.job.list.[]",
In: "body",
@ -70,7 +70,7 @@ func TestGenerate(t *testing.T) {
EnumList: nil,
},
&define.SwaggerParameterInput{
Type: consts.DataTypeInt,
Type: consts.DataTypeInt.String(),
Description: "年份",
Name: "person.job.year.[]",
In: "body",
@ -78,7 +78,7 @@ func TestGenerate(t *testing.T) {
EnumList: nil,
},
&define.SwaggerParameterInput{
Type: consts.DataTypeInt,
Type: consts.DataTypeInt.String(),
Description: "测试工作",
Name: "person.job.test",
In: "body",
@ -86,7 +86,7 @@ func TestGenerate(t *testing.T) {
EnumList: nil,
},
&define.SwaggerParameterInput{
Type: consts.DataTypeInt,
Type: consts.DataTypeInt.String(),
Description: "年龄",
Name: "age",
In: "body",
@ -94,7 +94,7 @@ func TestGenerate(t *testing.T) {
EnumList: []interface{}{18, 19, 20},
},
&define.SwaggerParameterInput{
Type: consts.DataTypeInt,
Type: consts.DataTypeInt.String(),
Description: "年龄",
Name: "test_list.[].age",
In: "body",
@ -102,7 +102,7 @@ func TestGenerate(t *testing.T) {
EnumList: []interface{}{18, 19, 20},
},
&define.SwaggerParameterInput{
Type: consts.DataTypeString,
Type: consts.DataTypeString.String(),
Description: "年龄",
Name: "test_list.[].name",
In: "body",
@ -110,7 +110,7 @@ func TestGenerate(t *testing.T) {
EnumList: nil,
},
&define.SwaggerParameterInput{
Type: consts.DataTypeMapAnyAny,
Type: consts.DataTypeMapAnyAny.String(),
Description: "测试global_map",
Name: "obj",
In: "body",
@ -124,19 +124,19 @@ func TestGenerate(t *testing.T) {
Description: "成功",
List: []*define.SwaggerResponseItemInput{
&define.SwaggerResponseItemInput{
Type: consts.DataTypeString,
Type: consts.DataTypeString.String(),
Description: "姓名",
Field: "nick_name",
IsRequired: false,
},
&define.SwaggerResponseItemInput{
Type: consts.DataTypeString,
Type: consts.DataTypeString.String(),
Description: "昵称",
Field: "person.nick_name",
IsRequired: false,
},
&define.SwaggerResponseItemInput{
Type: consts.DataTypeMapAnyAny,
Type: consts.DataTypeMapAnyAny.String(),
Description: "测试返回生成map",
Field: "obj",
IsRequired: false,

View File

@ -31,7 +31,7 @@ func GetParameterDefaultLocation(requestMethod string) string {
case http.MethodOptions:
fallthrough
case http.MethodTrace:
return consts.RequestLocationQuery
return consts.RequestDataLocationQuery.String()
case http.MethodPost:
fallthrough
case http.MethodPut:
@ -39,9 +39,9 @@ func GetParameterDefaultLocation(requestMethod string) string {
case http.MethodPatch: // RFC 5789
fallthrough
case http.MethodDelete:
return consts.RequestLocationBody
return consts.RequestDataLocationBody.String()
}
return consts.RequestLocationQuery
return consts.RequestDataLocationQuery.String()
}
// GetSwaggerType 基于输入的类型,
@ -51,11 +51,11 @@ func GetParameterDefaultLocation(requestMethod string) string {
// Date : 12:23 2024/4/22
func GetSwaggerType(inputType string) string {
convertTable := map[string]string{
consts.DataTypeString: "string",
consts.DataTypeInt: "integer",
consts.DataTypeUint: "integer",
consts.DataTypeFloat: "number",
consts.DataTypeBool: "boolean",
consts.DataTypeString.String(): "string",
consts.DataTypeInt.String(): "integer",
consts.DataTypeUint.String(): "integer",
consts.DataTypeFloat.String(): "number",
consts.DataTypeBool.String(): "boolean",
}
if _, exist := convertTable[inputType]; exist {
return convertTable[inputType]