mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-07 15:10:01 +08:00
fix: support PUT, PATCH, DELETE methods for request body definitions in swagger (#5239)
This commit is contained in:
@@ -8,28 +8,37 @@ import (
|
||||
apiSpec "github.com/zeromicro/go-zero/tools/goctl/api/spec"
|
||||
)
|
||||
|
||||
func isPostJson(ctx Context, method string, tp apiSpec.Type) (string, bool) {
|
||||
if !strings.EqualFold(method, http.MethodPost) {
|
||||
func isRequestBodyJson(ctx Context, method string, tp apiSpec.Type) (string, bool) {
|
||||
// Support HTTP methods that commonly use request bodies with JSON
|
||||
// POST, PUT, PATCH are standard methods with bodies
|
||||
// DELETE can also have a body (though less common)
|
||||
method = strings.ToUpper(method)
|
||||
if method != http.MethodPost && method != http.MethodPut &&
|
||||
method != http.MethodPatch && method != http.MethodDelete {
|
||||
return "", false
|
||||
}
|
||||
|
||||
structType, ok := tp.(apiSpec.DefineStruct)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
var isPostJson bool
|
||||
|
||||
var hasJsonField bool
|
||||
rangeMemberAndDo(ctx, structType, func(tag *apiSpec.Tags, required bool, member apiSpec.Member) {
|
||||
jsonTag, _ := tag.Get(tagJson)
|
||||
if !isPostJson {
|
||||
isPostJson = jsonTag != nil
|
||||
if !hasJsonField {
|
||||
hasJsonField = jsonTag != nil
|
||||
}
|
||||
})
|
||||
return structType.RawName, isPostJson
|
||||
|
||||
return structType.RawName, hasJsonField
|
||||
}
|
||||
|
||||
func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Parameter {
|
||||
if tp == nil {
|
||||
return []spec.Parameter{}
|
||||
}
|
||||
|
||||
structType, ok := tp.(apiSpec.DefineStruct)
|
||||
if !ok {
|
||||
return []spec.Parameter{}
|
||||
@@ -43,15 +52,13 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
|
||||
rangeMemberAndDo(ctx, structType, func(tag *apiSpec.Tags, required bool, member apiSpec.Member) {
|
||||
headerTag, _ := tag.Get(tagHeader)
|
||||
hasHeader := headerTag != nil
|
||||
|
||||
pathParameterTag, _ := tag.Get(tagPath)
|
||||
hasPathParameter := pathParameterTag != nil
|
||||
|
||||
formTag, _ := tag.Get(tagForm)
|
||||
hasForm := formTag != nil
|
||||
|
||||
jsonTag, _ := tag.Get(tagJson)
|
||||
hasJson := jsonTag != nil
|
||||
|
||||
if hasHeader {
|
||||
minimum, maximum, exclusiveMinimum, exclusiveMaximum := rangeValueFromOptions(headerTag.Options)
|
||||
resp = append(resp, spec.Parameter{
|
||||
@@ -75,6 +82,7 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if hasPathParameter {
|
||||
minimum, maximum, exclusiveMinimum, exclusiveMaximum := rangeValueFromOptions(pathParameterTag.Options)
|
||||
resp = append(resp, spec.Parameter{
|
||||
@@ -98,6 +106,7 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if hasForm {
|
||||
minimum, maximum, exclusiveMinimum, exclusiveMaximum := rangeValueFromOptions(formTag.Options)
|
||||
if strings.EqualFold(method, http.MethodGet) {
|
||||
@@ -145,8 +154,8 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if hasJson {
|
||||
minimum, maximum, exclusiveMinimum, exclusiveMaximum := rangeValueFromOptions(jsonTag.Options)
|
||||
if required {
|
||||
@@ -179,9 +188,10 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
|
||||
properties[jsonTag.Name] = schema
|
||||
}
|
||||
})
|
||||
|
||||
if len(properties) > 0 {
|
||||
if ctx.UseDefinitions {
|
||||
structName, ok := isPostJson(ctx, method, tp)
|
||||
structName, ok := isRequestBodyJson(ctx, method, tp)
|
||||
if ok {
|
||||
resp = append(resp, spec.Parameter{
|
||||
ParamProps: spec.ParamProps{
|
||||
@@ -213,5 +223,6 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
apiSpec "github.com/zeromicro/go-zero/tools/goctl/api/spec"
|
||||
)
|
||||
|
||||
func TestIsPostJson(t *testing.T) {
|
||||
func TestIsRequestBodyJson(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
method string
|
||||
@@ -18,13 +18,18 @@ func TestIsPostJson(t *testing.T) {
|
||||
{"POST with JSON", http.MethodPost, true, true},
|
||||
{"POST without JSON", http.MethodPost, false, false},
|
||||
{"GET with JSON", http.MethodGet, true, false},
|
||||
{"PUT with JSON", http.MethodPut, true, false},
|
||||
{"PUT with JSON", http.MethodPut, true, true},
|
||||
{"PUT without JSON", http.MethodPut, false, false},
|
||||
{"PATCH with JSON", http.MethodPatch, true, true},
|
||||
{"PATCH without JSON", http.MethodPatch, false, false},
|
||||
{"DELETE with JSON", http.MethodDelete, true, true},
|
||||
{"DELETE without JSON", http.MethodDelete, false, false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
testStruct := createTestStruct("TestStruct", tt.hasJson)
|
||||
_, result := isPostJson(testingContext(t), tt.method, testStruct)
|
||||
_, result := isRequestBodyJson(testingContext(t), tt.method, testStruct)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
@@ -41,6 +46,12 @@ func TestParametersFromType(t *testing.T) {
|
||||
}{
|
||||
{"POST JSON with definitions", http.MethodPost, true, true, 1, true},
|
||||
{"POST JSON without definitions", http.MethodPost, false, true, 1, true},
|
||||
{"PUT JSON with definitions", http.MethodPut, true, true, 1, true},
|
||||
{"PUT JSON without definitions", http.MethodPut, false, true, 1, true},
|
||||
{"PATCH JSON with definitions", http.MethodPatch, true, true, 1, true},
|
||||
{"PATCH JSON without definitions", http.MethodPatch, false, true, 1, true},
|
||||
{"DELETE JSON with definitions", http.MethodDelete, true, true, 1, true},
|
||||
{"DELETE JSON without definitions", http.MethodDelete, false, true, 1, true},
|
||||
{"GET with form", http.MethodGet, false, false, 1, false},
|
||||
{"POST with form", http.MethodPost, false, false, 1, false},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user