引入文档解析
This commit is contained in:
@ -9,7 +9,6 @@ package router
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// controller 解析controller有哪些方法要注册为接口
|
||||
@ -92,12 +91,14 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
|
||||
formType = methodType.In(2).Elem()
|
||||
}
|
||||
cfg.FormDataType = formType
|
||||
metaField, metaFieldExist := formType.FieldByName(FieldNameMeta)
|
||||
_, metaFieldExist := formType.FieldByName(FieldNameMeta)
|
||||
if !metaFieldExist {
|
||||
needRegister = false
|
||||
return
|
||||
}
|
||||
|
||||
cfg.ResultDataType = methodType.Out(0)
|
||||
if cfg.ResultDataType == nil {
|
||||
}
|
||||
if methodType.Out(1).Kind().String() != ErrorType {
|
||||
// 判断是否是实现 error接口的方法
|
||||
outputErrParse := false
|
||||
@ -115,23 +116,6 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
|
||||
return
|
||||
}
|
||||
}
|
||||
// 解析meta信息
|
||||
cfg.Path = metaField.Tag.Get(TagNamePath)
|
||||
cfg.RequestMethod = metaField.Tag.Get(TagNameMethod)
|
||||
cfg.Desc = metaField.Tag.Get(TagNameDesc)
|
||||
cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",")
|
||||
// 解析第一个返回值, 要求必须是结构体或者是map
|
||||
outputStrictModel := metaField.Tag.Get(TagNameOutputStrict)
|
||||
cfg.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true"
|
||||
if cfg.OutputStrict {
|
||||
// 开启输出严格模式校验
|
||||
if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map {
|
||||
panic(cfg.Path + " : 接口配置输出严格校验, 输出数据类型必须为 struct 或 *struct 或 map, 实际返回数据类型 : " + methodType.Out(0).Kind().String())
|
||||
return
|
||||
}
|
||||
}
|
||||
// 解析参数配置
|
||||
cfg.ParamList = c.parseParamConfig(formType)
|
||||
cfg.ApiLogicFunc = reflectMethod
|
||||
needRegister = true
|
||||
return
|
||||
|
@ -39,8 +39,8 @@ type UriConfig struct {
|
||||
TagList []string `json:"tag_list"` // 接口分组
|
||||
Desc string `json:"desc"` // 接口描述
|
||||
OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map
|
||||
ParamList []UriParam `json:"param_list"` // 参数信息表
|
||||
FormDataType reflect.Type `json:"-"` // 表单数据类型
|
||||
ResultDataType reflect.Type `json:"-"` // 返回值数据类型
|
||||
ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值
|
||||
ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑
|
||||
}
|
||||
|
43
router/doc.go
Normal file
43
router/doc.go
Normal file
@ -0,0 +1,43 @@
|
||||
// Package router ...
|
||||
//
|
||||
// Description : router ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2025-02-14 21:48
|
||||
package router
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
api_doc "git.zhangdeman.cn/gateway/api-doc"
|
||||
"git.zhangdeman.cn/gateway/api-doc/define"
|
||||
)
|
||||
|
||||
func NewDoc(info *define.Info, servers []*define.ServerItem) *Doc {
|
||||
return &Doc{
|
||||
instance: api_doc.NewOpenapiDoc(info, servers),
|
||||
}
|
||||
}
|
||||
|
||||
type Doc struct {
|
||||
instance *api_doc.Generate
|
||||
}
|
||||
|
||||
// Add 增加接口文档测试
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 21:55 2025/2/14
|
||||
func (d *Doc) Add(routePrefix string, paramType reflect.Type, resultType reflect.Type) {
|
||||
_ = d.instance.AddApiFromInAndOut(routePrefix, paramType, resultType)
|
||||
}
|
||||
|
||||
// Data 文档数据
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 21:59 2025/2/14
|
||||
func (d *Doc) Data() *define.OpenapiDoc {
|
||||
return d.instance.Doc()
|
||||
}
|
@ -8,6 +8,8 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -15,8 +17,18 @@ import (
|
||||
|
||||
type TestController struct{}
|
||||
|
||||
func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (any, error) {
|
||||
return formData, nil
|
||||
func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (TestOut, error) {
|
||||
return TestOut{
|
||||
FormData: formData,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type TestOut struct {
|
||||
Age int `json:"age" form:"age" binding:"min=20" err_msg:"年龄不能小于20"`
|
||||
Name string `json:"name" form:"name"`
|
||||
Test *Test `json:"test" form:"test"`
|
||||
Num *int64 `json:"num" form:"num"`
|
||||
FormData *TestForm `json:"form_data" form:"form_data"`
|
||||
}
|
||||
|
||||
type TestForm struct {
|
||||
@ -34,5 +46,7 @@ func Test_parseController(t *testing.T) {
|
||||
SetValidateErrTag("err_msg")
|
||||
s := NewServer(8080, nil)
|
||||
s.Group("test", nil, TestController{})
|
||||
byteData, _ := json.Marshal(s.docInstance.Data())
|
||||
fmt.Println(string(byteData))
|
||||
s.Start()
|
||||
}
|
||||
|
@ -9,9 +9,10 @@ package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// NewServer server实例
|
||||
@ -24,13 +25,15 @@ func NewServer(port int, option any) *server {
|
||||
panic("port should be greater than 80")
|
||||
}
|
||||
return &server{
|
||||
router: gin.Default(),
|
||||
router: gin.Default(),
|
||||
docInstance: NewDoc(nil, nil), // TODO : 配置相关信息
|
||||
}
|
||||
}
|
||||
|
||||
type server struct {
|
||||
router *gin.Engine
|
||||
port int
|
||||
router *gin.Engine
|
||||
port int
|
||||
docInstance *Doc
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
@ -56,6 +59,7 @@ func (s *server) Group(routerPrefix string, middlewareList []gin.HandlerFunc, cL
|
||||
for _, c := range cList {
|
||||
urlTable := cParser.Parse(c)
|
||||
for _, itemUriCfg := range urlTable {
|
||||
s.docInstance.Add(routerPrefix, itemUriCfg.FormDataType, itemUriCfg.ResultDataType)
|
||||
method := strings.ToUpper(itemUriCfg.RequestMethod)
|
||||
switch method {
|
||||
case http.MethodGet:
|
||||
|
Reference in New Issue
Block a user