openapi格式的文档基础生成 #3
@ -22,17 +22,12 @@ const (
|
|||||||
TagD = "d"
|
TagD = "d"
|
||||||
TagDefault = "default"
|
TagDefault = "default"
|
||||||
TagDeprecated = "deprecated"
|
TagDeprecated = "deprecated"
|
||||||
)
|
TagSummary = "summary"
|
||||||
|
TagPath = "path" // 接口的请求路径
|
||||||
const (
|
TagMethod = "method" // 接口的请求方法
|
||||||
TagNamePath = "path" // 接口的请求路径
|
TagUriTag = "tag" // 接口的tag
|
||||||
TagNameMethod = "method" // 接口的请求方法
|
TagOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值
|
||||||
TagNameUriTag = "tag" // 接口的tag
|
TagErrMsg = "err" // 验证失败错误信息tag
|
||||||
TagNameDesc = "desc" // 接口的描述
|
TagContentType = "content_type"
|
||||||
TagNameOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值
|
TagOutputContentType = "output_content_type"
|
||||||
TagNameBinding = "binding" // gin 内置的验证规则tag
|
|
||||||
TagNameValidate = "validate" // validator v10 默认的验证规则tag
|
|
||||||
TagNameErrMsg = "err" // 验证失败错误信息tag
|
|
||||||
TagNameContentType = "content_type"
|
|
||||||
TagNameOutputContentType = "output_content_type"
|
|
||||||
)
|
)
|
||||||
|
55
generate.go
55
generate.go
@ -177,17 +177,10 @@ func (g *Generate) AddApiFromInAndOut(paramType reflect.Type, resultType reflect
|
|||||||
if resultType.Kind() == reflect.Ptr {
|
if resultType.Kind() == reflect.Ptr {
|
||||||
resultType = resultType.Elem()
|
resultType = resultType.Elem()
|
||||||
}
|
}
|
||||||
baseCfg := g.parseBaseUriConfig(paramType)
|
baseCfg, err := g.parseBaseUriConfig(paramType)
|
||||||
if nil == baseCfg {
|
if nil != err {
|
||||||
return errors.New("baseCfg is nil")
|
return err
|
||||||
}
|
}
|
||||||
if baseCfg.Method == "" {
|
|
||||||
return errors.New("baseCfg.Method is empty")
|
|
||||||
}
|
|
||||||
if baseCfg.Uri == "" {
|
|
||||||
return errors.New("baseCfg.Uri is empty")
|
|
||||||
}
|
|
||||||
baseCfg.Method = strings.ToUpper(baseCfg.Method)
|
|
||||||
if _, exist := g.docData.Paths[baseCfg.Uri]; !exist {
|
if _, exist := g.docData.Paths[baseCfg.Uri]; !exist {
|
||||||
g.docData.Paths[baseCfg.Uri] = &define.PathConfig{}
|
g.docData.Paths[baseCfg.Uri] = &define.PathConfig{}
|
||||||
}
|
}
|
||||||
@ -238,16 +231,13 @@ func (g *Generate) AddApiFromInAndOut(paramType reflect.Type, resultType reflect
|
|||||||
http.MethodGet, http.MethodHead, http.MethodConnect, http.MethodOptions, http.MethodTrace,
|
http.MethodGet, http.MethodHead, http.MethodConnect, http.MethodOptions, http.MethodTrace,
|
||||||
}
|
}
|
||||||
if wrapper.ArrayType(paramMethod).Has(baseCfg.Method) >= 0 {
|
if wrapper.ArrayType(paramMethod).Has(baseCfg.Method) >= 0 {
|
||||||
|
cfg.RequestBody = nil // get类请求没有request body
|
||||||
// Get类请求, TODO : get类解析
|
// Get类请求, TODO : get类解析
|
||||||
// 参数解析
|
// 参数解析
|
||||||
g.ParseReadConfigParam(baseCfg, cfg, paramType)
|
g.ParseReadConfigParam(baseCfg, cfg, paramType)
|
||||||
// 返回值解析
|
} else {
|
||||||
g.AddComponentsSchema("", resultType.PkgPath(), resultType)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// post类解析
|
// post类解析
|
||||||
paramSchemaName := g.AddComponentsSchema("", paramType.PkgPath(), paramType)
|
paramSchemaName := g.AddComponentsSchema("", paramType.PkgPath(), paramType)
|
||||||
resultSchemaName := g.AddComponentsSchema("", resultType.PkgPath(), resultType)
|
|
||||||
for _, itemType := range baseCfg.ContentType {
|
for _, itemType := range baseCfg.ContentType {
|
||||||
cfg.RequestBody.Content[itemType] = &define.Media{
|
cfg.RequestBody.Content[itemType] = &define.Media{
|
||||||
Schema: &define.Schema{
|
Schema: &define.Schema{
|
||||||
@ -258,6 +248,9 @@ func (g *Generate) AddApiFromInAndOut(paramType reflect.Type, resultType reflect
|
|||||||
Encoding: nil,
|
Encoding: nil,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// 无论什么请求, 对于result解析逻辑一致
|
||||||
|
resultSchemaName := g.AddComponentsSchema("", resultType.PkgPath(), resultType)
|
||||||
for _, itemOutputType := range baseCfg.OutputContentType {
|
for _, itemOutputType := range baseCfg.OutputContentType {
|
||||||
cfg.Responses[fmt.Sprintf("%v", http.StatusOK)].Content[itemOutputType] = &define.Media{
|
cfg.Responses[fmt.Sprintf("%v", http.StatusOK)].Content[itemOutputType] = &define.Media{
|
||||||
Schema: &define.Schema{
|
Schema: &define.Schema{
|
||||||
@ -568,11 +561,16 @@ func (g *Generate) setStructFieldProperty(schemaName string, structField reflect
|
|||||||
g.docData.Components.Schemas[schemaName].Properties[ParseStructField.GetParamName(structField)].Enum = ValidateRule.Enum(structField)
|
g.docData.Components.Schemas[schemaName].Properties[ParseStructField.GetParamName(structField)].Enum = ValidateRule.Enum(structField)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Generate) parseBaseUriConfig(paramType reflect.Type) *define.UriBaseConfig {
|
// parseBaseUriConfig 通过Meta字段解析Uri基础配置信息
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:13 2025/2/14
|
||||||
|
func (g *Generate) parseBaseUriConfig(paramType reflect.Type) (*define.UriBaseConfig, error) {
|
||||||
// 解析meta信息
|
// 解析meta信息
|
||||||
metaField, metaFieldExist := paramType.FieldByName("Meta")
|
metaField, metaFieldExist := paramType.FieldByName("Meta")
|
||||||
if !metaFieldExist {
|
if !metaFieldExist {
|
||||||
return nil
|
return nil, errors.New("Meta field not found")
|
||||||
}
|
}
|
||||||
res := &define.UriBaseConfig{
|
res := &define.UriBaseConfig{
|
||||||
Uri: "",
|
Uri: "",
|
||||||
@ -586,16 +584,23 @@ func (g *Generate) parseBaseUriConfig(paramType reflect.Type) *define.UriBaseCon
|
|||||||
ResultList: nil,
|
ResultList: nil,
|
||||||
Deprecated: false,
|
Deprecated: false,
|
||||||
}
|
}
|
||||||
res.Uri = metaField.Tag.Get(define.TagNamePath)
|
res.Uri = metaField.Tag.Get(define.TagPath)
|
||||||
res.Method = metaField.Tag.Get(define.TagNameMethod)
|
res.Method = strings.ToUpper(metaField.Tag.Get(define.TagMethod))
|
||||||
res.Description = metaField.Tag.Get(define.TagNameDesc)
|
res.Description = metaField.Tag.Get(define.TagDesc)
|
||||||
res.TagList = strings.Split(metaField.Tag.Get(define.TagNameUriTag), ",")
|
res.TagList = strings.Split(metaField.Tag.Get(define.TagUriTag), ",")
|
||||||
// 解析第一个返回值, 要求必须是结构体或者是map
|
// 解析第一个返回值, 要求必须是结构体或者是map
|
||||||
outputStrictModel := metaField.Tag.Get(define.TagNameOutputStrict)
|
outputStrictModel := metaField.Tag.Get(define.TagOutputStrict)
|
||||||
res.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true"
|
res.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true"
|
||||||
deprecated := metaField.Tag.Get(define.TagDeprecated)
|
deprecated := metaField.Tag.Get(define.TagDeprecated)
|
||||||
res.Deprecated = deprecated == "1" || deprecated == "true"
|
res.Deprecated = deprecated == "1" || deprecated == "true"
|
||||||
res.ContentType = strings.Split(metaField.Tag.Get(define.TagNameContentType), ",")
|
res.ContentType = strings.Split(metaField.Tag.Get(define.TagContentType), ",")
|
||||||
res.OutputContentType = strings.Split(metaField.Tag.Get(define.TagNameOutputContentType), ",")
|
res.OutputContentType = strings.Split(metaField.Tag.Get(define.TagOutputContentType), ",")
|
||||||
return res
|
res.Summary = ParseStructField.Summary(metaField)
|
||||||
|
if res.Method == "" {
|
||||||
|
return nil, errors.New("baseCfg.Method is empty")
|
||||||
|
}
|
||||||
|
if res.Uri == "" {
|
||||||
|
return nil, errors.New("baseCfg.Uri is empty")
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
}
|
}
|
||||||
|
@ -126,3 +126,18 @@ func (psf parseStructField) Deprecated(structField reflect.StructField) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Summary 摘要信息
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:15 2025/2/14
|
||||||
|
func (psf parseStructField) Summary(structField reflect.StructField) string {
|
||||||
|
defaultTagList := []string{define.TagSummary}
|
||||||
|
for _, tag := range defaultTagList {
|
||||||
|
if tagVal, exist := structField.Tag.Lookup(tag); exist && len(tagVal) > 0 {
|
||||||
|
return tagVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return psf.GetParamName(structField)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user