gf icon indicating copy to clipboard operation
gf copied to clipboard

fix(net/goai): fix openapi miss `required` tag of `BizRequest` when set `CommonRequest`

Open wufeng5702 opened this issue 1 year ago • 1 comments

Fixes #3605


Anthor Question

When I was debugging, I found that tags such as v: "min",v: "max" were not rendered in the openapi.json Is this as expected?

Example

  • Request & Response

    type CreateReq struct {
        g.Meta `path:"/Schema" tags:"schema" method:"POST" summary:"Create"`
    
        Option   string `dc:"option field"`
        Required string `v:"required" dc:"required field"`
        Min      int    `v:"min:1" d:"100" dc:"minimum value"`
        Max      int    `v:"max:10" d:"-1" dc:"maximum value"`
    }
    type CreateRes struct {
        Option   string `dc:"option field"`
        Required string `v:"required" dc:"required field"`
        Min      int    `v:"min:1" d:"200" dc:"minimum value"`
        Max      int    `v:"max:10" d:"-2" dc:"maximum value"`
    }
    
  • Swagger UI 图片

Demo Code
package main

import (
	"context"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

func main() {
	s := g.Server()
	s.Use(ghttp.MiddlewareHandlerResponse)

	s.BindObject("/v1", &Controller{})
	s.BindHandler("/status/:status", func(r *ghttp.Request) {
		r.Response.Write("Error status ", r.Get("status"), " found")
	})
	s.BindStatusHandler(404, func(r *ghttp.Request) {
		r.SetError(nil)
		r.Response.RedirectTo("status/404")
	})

	// TODO support Min, Max, MinLength, MaxLength

	// Custom enhance API document.
	enhanceOpenAPIDoc(s)
	s.SetOpenApiPath("/api.json")
	s.SetSwaggerPath("/swagger")

	s.SetPort(8999)
	// Just run the server.
	s.Run()
}

func enhanceOpenAPIDoc(s *ghttp.Server) {
	openapi := s.GetOpenApi()

	openapi.Config.CommonRequest = CommonReq{}
	openapi.Config.CommonResponse = ghttp.DefaultHandlerResponse{}
	openapi.Config.CommonResponseDataField = `Data`
}

type CommonReq struct {
	CommonOption   string `dc:"option field in common"`
	CommonRequired string `v:"required" dc:"required field in common"`
	CommonMin      int    `v:"min:-1" d:"88" dc:"minimum value in common"`
	CommonMax      int    `v:"max:10" d:"-8" dc:"maximum value in common"`
}

type Controller struct{}

type CreateReq struct {
	g.Meta `path:"/Schema" tags:"schema" method:"POST" summary:"Create"`

	Option   string `dc:"option field"`
	Required string `v:"required" dc:"required field"`
	Min      int    `v:"min:1" d:"100" dc:"minimum value"`
	Max      int    `v:"max:10" d:"-1" dc:"maximum value"`
}
type CreateRes struct {
	Option   string `dc:"option field"`
	Required string `v:"required" dc:"required field"`
	Min      int    `v:"min:1" d:"200" dc:"minimum value"`
	Max      int    `v:"max:10" d:"-2" dc:"maximum value"`
}

func (c *Controller) Create(ctx context.Context, req *CreateReq) (res *CreateRes, err error) {
	return nil, nil
}

type DeleteReq struct {
	g.Meta `path:"/Schema" tags:"schema" method:"DELETE" summary:"Delete"`

	Option   string `dc:"option field"`
	Required string `v:"required" dc:"required field"`
	Min      int    `v:"min:1" d:"300" dc:"minimum value"`
	Max      int    `v:"max:10" d:"-3" dc:"maximum value"`
}
type DeleteRes struct {
	Option   string `dc:"option field"`
	Required string `v:"required" dc:"required field"`
	Min      int    `v:"min:1" d:"400" dc:"minimum value"`
	Max      int    `v:"max:10" d:"-4" dc:"maximum value"`
}

func (c *Controller) Delete(ctx context.Context, req *DeleteReq) (res *DeleteRes, err error) {
	return nil, nil
}

type UpdateReq struct {
	g.Meta `path:"/Schema" tags:"schema" method:"PUT" summary:"Update"`

	Option   string `dc:"option field"`
	Required string `v:"required" dc:"required field"`
	Min      int    `v:"min:1" d:"500" dc:"minimum value"`
	Max      int    `v:"max:10" d:"-5" dc:"maximum value"`
}

type UpdateRes struct {
	Option   string `dc:"option field"`
	Required string `v:"required" dc:"required field"`
	Min      int    `v:"min:1" d:"600" dc:"minimum value"`
	Max      int    `v:"max:10" d:"-6" dc:"maximum value"`
}

func (c *Controller) Update(ctx context.Context, req *UpdateReq) (res *UpdateRes, err error) {
	return nil, nil
}

type GetReq struct {
	g.Meta `path:"/Schema" tags:"schema" method:"get" summary:"Get"`

	Option   string `dc:"option field"`
	Required string `v:"required" dc:"required field"`
	Min      int    `v:"min:1" d:"700" dc:"minimum value"`
	Max      int    `v:"max:10" d:"-7" dc:"maximum value"`
}
type GetRes struct {
	Option   string `dc:"option field"`
	Required string `v:"required" dc:"required field"`
	Min      int    `v:"min:1" d:"800" dc:"minimum value"`
	Max      int    `v:"max:10" d:"-8" dc:"maximum value"`
}

func (c *Controller) Get(ctx context.Context, req *GetReq) (res *GetRes, err error) {
	return nil, nil
}

wufeng5702 avatar Aug 10 '24 18:08 wufeng5702

Quality Gate Failed Quality Gate failed

Failed conditions
9.4% Duplication on New Code (required ≤ 3%)

See analysis details on SonarCloud

sonarqubecloud[bot] avatar Aug 10 '24 18:08 sonarqubecloud[bot]