From 39f9c3d67f51a4285897830a011beba8c931eae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 14 Feb 2025 11:47:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E6=A1=A3=E7=94=9F=E6=88=90=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8D=B3=E7=B3=BBurl=E4=B8=AD=E7=9A=84=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- define/openapi.go | 23 ++++++++++++----------- generate.go | 21 ++++++++++++++++++++- parser_test.go | 7 +++++++ 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/define/openapi.go b/define/openapi.go index 09f1adb..f536588 100644 --- a/define/openapi.go +++ b/define/openapi.go @@ -100,17 +100,17 @@ type ExternalDocs struct { // // Date : 12:29 2024/7/19 type PathConfigParameter struct { - Name string `json:"name"` // 参数名称 - In string `json:"in"` // 必选. 参数的位置,可能的值有 "query", "header", "path" 或 "cookie"。 - Description string `json:"description"` // 对此参数的简要描述,这里可以包含使用示例。CommonMark syntax可以被用来呈现富文本格式. - Required bool `json:"required"` // 标明此参数是否是必选参数。如果 参数位置 的值是 path,那么这个参数一定是 必选 的因此这里的值必须是true。其他的则视情况而定。此字段的默认值是false。 - Deprecated bool `json:"deprecated"` // 标明一个参数是被弃用的而且应该尽快移除对它的使用。 - Schema *Schema `json:"schema,omitempty"` // 定义适用于此参数的类型结构。 Schema 对象 | Reference 对象 - AllowEmptyValue bool `json:"allowEmptyValue"` // 设置是否允许传递空参数,这只在参数值为query时有效,默认值是false。如果同时指定了style属性且值为n/a(无法被序列化),那么此字段 allowEmptyValue应该被忽略。 - Style string `json:"style"` // 描述根据参数值类型的不同如何序列化参数。默认值为(基于in字段的值):query 对应 form;path 对应 simple; header 对应 simple; cookie 对应 form。 - Explode bool `json:"explode"` // 当这个值为true时,参数值类型为array或object的参数使用数组内的值或对象的键值对生成带分隔符的参数值。对于其他类型的参数,这个字段没有任何影响。当 style 是 form时,这里的默认值是 true,对于其他 style 值类型,默认值是false。 - AllowReserved bool `json:"allowReserved"` // 决定此参数的值是否允许不使用%号编码使用定义于 RFC3986内的保留字符 :/?#[]@!$&'()*+,;=。 这个属性仅用于in的值是query时,此字段的默认值是false。 - Ref string `json:"$ref"` // 一个允许引用规范内部的其他部分或外部规范的对象。 Reference 对象 定义于 JSON Reference 且遵循相同的结构、行为和规则。 + Name string `json:"name"` // 参数名称 + In string `json:"in"` // 必选. 参数的位置,可能的值有 "query", "header", "path" 或 "cookie"。 + Description string `json:"description"` // 对此参数的简要描述,这里可以包含使用示例。CommonMark syntax可以被用来呈现富文本格式. + Required bool `json:"required"` // 标明此参数是否是必选参数。如果 参数位置 的值是 path,那么这个参数一定是 必选 的因此这里的值必须是true。其他的则视情况而定。此字段的默认值是false。 + Deprecated bool `json:"deprecated"` // 标明一个参数是被弃用的而且应该尽快移除对它的使用。 + Schema *Schema `json:"schema,omitempty,omitempty"` // 定义适用于此参数的类型结构。 Schema 对象 | Reference 对象 + AllowEmptyValue bool `json:"allowEmptyValue"` // 设置是否允许传递空参数,这只在参数值为query时有效,默认值是false。如果同时指定了style属性且值为n/a(无法被序列化),那么此字段 allowEmptyValue应该被忽略。 + Style string `json:"style,omitempty"` // 描述根据参数值类型的不同如何序列化参数。默认值为(基于in字段的值):query 对应 form;path 对应 simple; header 对应 simple; cookie 对应 form。 + Explode bool `json:"explode,omitempty"` // 当这个值为true时,参数值类型为array或object的参数使用数组内的值或对象的键值对生成带分隔符的参数值。对于其他类型的参数,这个字段没有任何影响。当 style 是 form时,这里的默认值是 true,对于其他 style 值类型,默认值是false。 + AllowReserved bool `json:"allowReserved,omitempty"` // 决定此参数的值是否允许不使用%号编码使用定义于 RFC3986内的保留字符 :/?#[]@!$&'()*+,;=。 这个属性仅用于in的值是query时,此字段的默认值是false。 + Ref string `json:"$ref,omitempty"` // 一个允许引用规范内部的其他部分或外部规范的对象。 Reference 对象 定义于 JSON Reference 且遵循相同的结构、行为和规则。 } // Schema ... @@ -133,6 +133,7 @@ type Schema struct { Type string `json:"type,omitempty"` // 类型 Items *PropertyXOf `json:"items,omitempty"` // items 必须存在如果 type 的值是 array。 Ref string `json:"$ref,omitempty"` // 类型引用 + Format string `json:"format,omitempty"` // 格式化类型 } // Property 是从 JSON Schema 提取出来的,但是做了一些调整以适应 OpenAPI Specification。 diff --git a/generate.go b/generate.go index e644edd..09601af 100644 --- a/generate.go +++ b/generate.go @@ -208,7 +208,7 @@ func (g *Generate) AddApiFromInAndOut(paramType reflect.Type, resultType reflect Description: baseCfg.Description, ExternalDocs: nil, OperationID: baseCfg.Method + "-" + defaultPkgPath, - Parameters: nil, + Parameters: make([]*define.PathConfigParameter, 0), RequestBody: &define.RequestBody{ Required: true, Description: "", @@ -225,6 +225,25 @@ func (g *Generate) AddApiFromInAndOut(paramType reflect.Type, resultType reflect Security: nil, Servers: nil, } + // 解析绑定在url中的参数 + if paramList := define.UriParamRegexp.FindAllString(baseCfg.Uri, -1); len(paramList) > 0 { + for _, param := range paramList { + param = strings.TrimPrefix(param, "{") + param = strings.TrimSuffix(param, "}") + cfg.Parameters = append(cfg.Parameters, &define.PathConfigParameter{ + Name: param, + In: consts.SwaggerParameterInPath, + Description: param, + Required: true, + Deprecated: false, + Schema: &define.Schema{ + Type: consts.SwaggerDataTypeString, + Format: consts.DataTypeString.String(), + }, + AllowEmptyValue: false, + }) + } + } for _, itemType := range baseCfg.ContentType { cfg.RequestBody.Content[itemType] = &define.Media{ Schema: &define.Schema{ diff --git a/parser_test.go b/parser_test.go index 806a7b8..a00cbda 100644 --- a/parser_test.go +++ b/parser_test.go @@ -35,6 +35,11 @@ func Test_parser_Openapi3(t *testing.T) { Name string `json:"name" d:"zhang" desc:"用户姓名" binding:"required"` Age string `json:"age" d:"18" desc:"年龄" binding:"required,oneof=12 13 18 90"` } + type UserPut struct { + Meta `json:"-" deprecated:"false" path:"/user/put/{put_user_id}" method:"PUT" desc:"测试接口" tag:"用户,搜索" content_type:"application/json" output_content_type:"application/json"` + Name string `json:"name" d:"zhang" desc:"用户姓名" binding:"required"` + Age string `json:"age" d:"18" desc:"年龄" binding:"required,oneof=12 13 18 90"` + } type List struct { Total int64 `json:"total" binding:"required"` UserList []User `json:"user_list"` @@ -42,6 +47,7 @@ func Test_parser_Openapi3(t *testing.T) { var o List var f User var fd UserDelete + var up UserPut g := NewOpenapiDoc(nil, []*define.ServerItem{ &define.ServerItem{ Url: "http://127.0.0.1/v1", @@ -56,6 +62,7 @@ func Test_parser_Openapi3(t *testing.T) { }) g.AddApiFromInAndOut(reflect.TypeOf(f), reflect.TypeOf(o)) g.AddApiFromInAndOut(reflect.TypeOf(fd), reflect.TypeOf(o)) + g.AddApiFromInAndOut(reflect.TypeOf(up), reflect.TypeOf(o)) byteData, _ := json.Marshal(g.docData) fmt.Println(string(byteData)) }