mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
add short typed tag mapping for summary/description for package goai;add suffix checks for request/response struct naming
This commit is contained in:
@ -11,7 +11,7 @@ func main() {
|
||||
s.BindHandler("/page/ajax", func(r *ghttp.Request) {
|
||||
page := r.GetPage(100, 10)
|
||||
page.AjaxActionName = "DoAjax"
|
||||
buffer, _ := gview.ParseContent(`
|
||||
buffer, _ := gview.ParseContent(r.Context(), `
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
|
||||
@ -161,6 +161,24 @@ func (s *Server) checkAndCreateFuncInfo(f interface{}, pkgPath, structName, meth
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if !gstr.HasSuffix(reflectType.In(1).String(), `Req`) {
|
||||
err = gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
`invalid struct naming for request: defined as "%s", but it should be named with "Req" suffix like "xxxReq"`,
|
||||
reflectType.In(1).String(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if !gstr.HasSuffix(reflectType.Out(0).String(), `Res`) {
|
||||
err = gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
`invalid struct naming for response: defined as "%s", but it should be named with "Res" suffix like "xxxRes"`,
|
||||
reflectType.Out(0).String(),
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
info.Func = handlerFunc
|
||||
info.Type = reflect.TypeOf(f)
|
||||
|
||||
@ -87,6 +87,10 @@ const (
|
||||
var (
|
||||
defaultReadContentTypes = []string{`application/json`}
|
||||
defaultWriteContentTypes = []string{`application/json`}
|
||||
shortTypeMapForTag = map[string]string{
|
||||
"sum": "summary",
|
||||
"des": "description",
|
||||
}
|
||||
)
|
||||
|
||||
// New creates and returns a OpenApiV3 implements object.
|
||||
@ -213,6 +217,15 @@ func (oai *OpenApiV3) golangTypeToSchemaName(t reflect.Type) string {
|
||||
return schemaName
|
||||
}
|
||||
|
||||
func (oai *OpenApiV3) fileMapWithShortTags(m map[string]string) map[string]string {
|
||||
for k, v := range shortTypeMapForTag {
|
||||
if m[v] == "" && m[k] != "" {
|
||||
m[v] = m[k]
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func formatRefToBytes(ref string) []byte {
|
||||
return []byte(fmt.Sprintf(`{"$ref":"#/components/schemas/%s"}`, ref))
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ func (oai *OpenApiV3) newParameterRefWithStructMethod(field *structs.Field, meth
|
||||
parameter.Name = field.Name()
|
||||
}
|
||||
if len(tagMap) > 0 {
|
||||
err := gconv.Struct(tagMap, parameter)
|
||||
err := gconv.Struct(oai.fileMapWithShortTags(tagMap), parameter)
|
||||
if err != nil {
|
||||
return nil, gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Parameter failed`)
|
||||
}
|
||||
|
||||
@ -130,10 +130,10 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
}
|
||||
|
||||
if len(inputMetaMap) > 0 {
|
||||
if err := gconv.Struct(inputMetaMap, &path); err != nil {
|
||||
if err := gconv.Struct(oai.fileMapWithShortTags(inputMetaMap), &path); err != nil {
|
||||
return gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Path failed`)
|
||||
}
|
||||
if err := gconv.Struct(inputMetaMap, &operation); err != nil {
|
||||
if err := gconv.Struct(oai.fileMapWithShortTags(inputMetaMap), &operation); err != nil {
|
||||
return gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Operation failed`)
|
||||
}
|
||||
}
|
||||
@ -208,7 +208,7 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
}
|
||||
)
|
||||
if len(outputMetaMap) > 0 {
|
||||
if err := gconv.Struct(outputMetaMap, &response); err != nil {
|
||||
if err := gconv.Struct(oai.fileMapWithShortTags(outputMetaMap), &response); err != nil {
|
||||
return gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Response failed`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ func (oai *OpenApiV3) newSchemaRefWithGolangType(golangType reflect.Type, tagMap
|
||||
}
|
||||
)
|
||||
if len(tagMap) > 0 {
|
||||
if err := gconv.Struct(tagMap, schema); err != nil {
|
||||
if err := gconv.Struct(oai.fileMapWithShortTags(tagMap), schema); err != nil {
|
||||
return nil, gerror.WrapCode(gcode.CodeInternalError, err, `mapping struct tags to Schema failed`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,3 +561,61 @@ func TestOpenApiV3_CommonResponse_SubDataField(t *testing.T) {
|
||||
t.Assert(len(oai.Paths["/index"].Get.Responses["200"].Value.Content["application/json"].Schema.Value.Properties[`Response`].Value.Properties), 7)
|
||||
})
|
||||
}
|
||||
|
||||
func TestOpenApiV3_ShortTags(t *testing.T) {
|
||||
type CommonReq struct {
|
||||
AppId int64 `json:"appId" v:"required" in:"path" des:"应用Id" sum:"应用Id Summary"`
|
||||
ResourceId string `json:"resourceId" in:"query" des:"资源Id" sum:"资源Id Summary"`
|
||||
}
|
||||
type SetSpecInfo struct {
|
||||
StorageType string `v:"required|in:CLOUD_PREMIUM,CLOUD_SSD,CLOUD_HSSD" des:"StorageType"`
|
||||
Shards int32 `des:"shards 分片数" sum:"Shards Summary"`
|
||||
Params []string `des:"默认参数(json 串-ClickHouseParams)" sum:"Params Summary"`
|
||||
}
|
||||
type CreateResourceReq struct {
|
||||
CommonReq
|
||||
gmeta.Meta `path:"/CreateResourceReq" method:"POST" tags:"default" sum:"CreateResourceReq sum"`
|
||||
Name string `des:"实例名称"`
|
||||
Product string `des:"业务类型"`
|
||||
Region string `v:"required" des:"区域"`
|
||||
SetMap map[string]*SetSpecInfo `v:"required" des:"配置Map"`
|
||||
SetSlice []SetSpecInfo `v:"required" des:"配置Slice"`
|
||||
}
|
||||
|
||||
type CreateResourceRes struct {
|
||||
gmeta.Meta `des:"Demo Response Struct"`
|
||||
FlowId int64 `des:"创建实例流程id"`
|
||||
}
|
||||
|
||||
f := func(ctx context.Context, req *CreateResourceReq) (res *CreateResourceRes, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
err error
|
||||
oai = goai.New()
|
||||
)
|
||||
err = oai.Add(goai.AddInput{
|
||||
Path: "/test1/{appId}",
|
||||
Method: goai.HttpMethodPut,
|
||||
Object: f,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
|
||||
err = oai.Add(goai.AddInput{
|
||||
Path: "/test1/{appId}",
|
||||
Method: goai.HttpMethodPost,
|
||||
Object: f,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
//fmt.Println(oai.String())
|
||||
// Schema asserts.
|
||||
t.Assert(len(oai.Components.Schemas), 3)
|
||||
t.Assert(oai.Paths[`/test1/{appId}`].Summary, `CreateResourceReq sum`)
|
||||
t.Assert(oai.
|
||||
Components.
|
||||
Schemas[`github.com.gogf.gf.v2.protocol.goai_test.CreateResourceReq`].
|
||||
Value.Properties[`resourceId`].Value.Description, `资源Id`)
|
||||
})
|
||||
}
|
||||
|
||||
@ -21,8 +21,7 @@ const (
|
||||
)
|
||||
|
||||
// Data retrieves and returns all metadata from `object`.
|
||||
// It automatically parses and caches the tag string from "Mata" attribute as its metadata.
|
||||
func Data(object interface{}) map[string]interface{} {
|
||||
func Data(object interface{}) map[string]string {
|
||||
reflectType, err := structs.StructType(object)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -30,20 +29,20 @@ func Data(object interface{}) map[string]interface{} {
|
||||
if field, ok := reflectType.FieldByName(metaAttributeName); ok {
|
||||
var (
|
||||
tags = structs.ParseTag(string(field.Tag))
|
||||
data = make(map[string]interface{}, len(tags))
|
||||
data = make(map[string]string, len(tags))
|
||||
)
|
||||
for k, v := range tags {
|
||||
data[k] = v
|
||||
}
|
||||
return data
|
||||
}
|
||||
return map[string]interface{}{}
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
// Get retrieves and returns specified metadata by `key` from `object`.
|
||||
func Get(object interface{}, key string) *gvar.Var {
|
||||
v := Data(object)[key]
|
||||
if v == nil {
|
||||
v, ok := Data(object)[key]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return gvar.New(v)
|
||||
|
||||
Reference in New Issue
Block a user