V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xxjwxc
V2EX  ›  程序员

golang gin 框架中间件 注解路由,自动参数绑定工具

  •  
  •   xxjwxc ·
    xxjwxc · 2019-12-10 20:02:21 +08:00 · 4173 次点击
    这是一个创建于 1591 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ginprc

    Mentioned in Awesome Go

    golang gin 参数自动绑定工具

    • 支持 rpc 自动映射
    • 支持对象注册
    • 支持注解路由
    • 基于 go-gin 的 json restful 风格的 golang 基础库
    • 自带请求参数过滤及绑定实现 binding:"required" validator
    • 代码注册简单且支持多种注册方式

    api 接口说明

    支持 3 种接口模式

    • func(*gin.Context) //go-gin 原始接口

      func(*api.Context) //自定义的 context 类型

    • func(*api.Context,req) //自定义的 context 类型,带 request 请求参数

      func(*api.Context,*req)

    • func(*gin.Context,*req) //go-gin context 类型,带 request 请求参数

      func(*gin.Context,req)

    一,参数自动绑定

      package main
    
    import (
    	"fmt"
    	"net/http"
    
    	_ "ginweb/routers" // debug 模式需要添加[mod]/routers 注册注解路由
    
    	"github.com/gin-gonic/gin"
    	"github.com/xxjwxc/ginrpc"
    	"github.com/xxjwxc/ginrpc/api"
    )
    
    type ReqTest struct {
    	Access_token string `json:"access_token"`
    	UserName     string `json:"user_name" binding:"required"` // 带校验方式
    	Password     string `json:"password"`
    }
    
    //TestFun4 带自定义 context 跟已解析的 req 参数回调方式
    func TestFun4(c *gin.Context, req ReqTest) {
    	fmt.Println(c.Params)
    	fmt.Println(req)
    
    	c.JSON( http.StatusOK, req)
    }
    
    func main() {
    	base := ginrpc.New() 
    	router := gin.Default()
    	router.POST("/test4", base.HandlerFunc(TestFun4))
    	base.RegisterHandlerFunc(router, []string{"post", "get"}, "/test", TestFun4) // 多种请求方式注册
    	router.Run(":8080")
    }
    
    
    • curl

      curl 'http://127.0.0.1:8080/test4' -H 'Content-Type: application/json' -d '{"access_token":"111", "user_name":"222", "password":"333"}'
      
      

    二,对象注册(注解路由)

    初始化项目(本项目以 ginweb 为名字)

    ``` go mod init ginweb ```
    

    代码 详细地址>>

      package main
    
    import (
    	"fmt"
    	"net/http"
    
    	_ "ginweb/routers" // debug 模式需要添加[mod]/routers 注册注解路由
    
    	"github.com/gin-gonic/gin"
    	"github.com/xxjwxc/ginrpc"
    	"github.com/xxjwxc/ginrpc/api"
    )
    
    type ReqTest struct {
    	Access_token string `json:"access_token"`
    	UserName     string `json:"user_name" binding:"required"` // 带校验方式
    	Password     string `json:"password"`
    }
    
    // Hello ...
    type Hello struct {
    }
    
    // Hello 带注解路由(参考 beego 形式)
    // @router /block [post,get]
    func (s *Hello) Hello(c *api.Context, req *ReqTest) {
    	fmt.Println(req)
    	fmt.Println(s.Index)
    	c.JSON( http.StatusOK, "ok")
    }
    
    // Hello2 不带注解路由(参数为 2 默认 post)
    func (s *Hello) Hello2(c *gin.Context, req ReqTest) {
    	fmt.Println(req)
    	fmt.Println(s.Index)
    	c.JSON( http.StatusOK, "ok")
    }
    
    
    func main() {
    	base := ginrpc.New(ginrpc.WithCtx(func(c *gin.Context) interface{} {
    		return api.NewCtx(c)
    	}), ginrpc.WithDebug(true), ginrpc.WithGroup("xxjwxc"))
    
    	router := gin.Default()
    	base.Register(router, new(Hello))                          // 对象注册 like(go-micro)
    	// or base.Register(router, new(Hello)) 
    	router.Run(":8080")
    }
    

    -注解路由相关说明

     // @router /block [post,get]
    
    @router 标记 
    
    /block 路由
     
    [post,get] method 调用方式
    
    

    1. 注解路由会自动创建[mod]/routers/gen_router.go 文件 需要在调用时加:

    ```
    _ "[mod]/routers" // debug 模式需要添加[mod]/routers 注册注解路由
    
    ```
    
    默认也会在项目根目录生成[gen_router.data]文件(保留此文件,可以不用添加上面代码嵌入)
    

    2. 注解路由调用方式:

    详细请看 demo  [ginweb](/sample/ginweb)
    

    3. 相关参数说明

    ginrpc.WithCtx: 设置自定义 context
    
    ginrpc.WithDebug(true) : 设置 debug 模式
    
    ginrpc.WithGroup("xxjwxc") : 添加路由前缀 (也可以使用 gin.Group 分组)
    
    ginrpc.WithBigCamel(true) : 设置大驼峰标准(false 为 web 模式,_,小写)
    
    [更多]( https://godoc.org/github.com/xxjwxc/ginrpc)
    

    4. 执行 curl,可以自动参数绑定。直接看结果

    curl 'http://127.0.0.1:8080/xxjwxc/block' -H 'Content-Type: application/json' -d '{"access_token":"111", "user_name":"222", "password":"333"}'
    
    curl 'http://127.0.0.1:8080/xxjwxc/hello.hello2' -H 'Content-Type: application/json' -d '{"access_token":"111", "user_name":"222", "password":"333"}'
    

    下一步

    1.导出 api 文档
    
    2.导出 postman 测试配置
    

    代码地址: ginprc 如果喜欢请给星支持

    7 条回复    2019-12-11 00:25:14 +08:00
    mritd
        1
    mritd  
       2019-12-10 20:41:23 +08:00
    可能个人原因,有点不太喜欢这种注释的方式扫;然后也是 写 spring 习惯了想弄一个这种无侵入的方式;
    目前我的方案是类似 caddy1 的插件方式,全局 map,然后每个路由 func 通过调用一个 register 塞进 map 里,后面延迟初始化,代码类似这个 https://github.com/mritd/ginmvc/blob/master/routers/user.go#L20
    xxjwxc
        2
    xxjwxc  
    OP
       2019-12-10 22:53:32 +08:00
    @mritd 你这是手动创建的吧? ginrpc 也支持手动创建。自动创建是可以省掉注册路由这一块。我这个框架是参考 go-micro 的注册方式,其实可以不用添加注解路由。它会执行默认注册路由方式。比如 hello.Hello
    Trim21
        3
    Trim21  
       2019-12-10 23:19:12 +08:00 via Android
    这样的话是不是也有可能像 fastapi 一样从 query 和 path 里面绑定数据…
    cuberlzy
        4
    cuberlzy  
       2019-12-11 00:15:36 +08:00
    我实现了一个像如下的
    cuberlzy
        5
    cuberlzy  
       2019-12-11 00:19:10 +08:00
    我实现了一个像如下的

    ``` go
    func (* xxxService) Hello(req *request.Hello, session *base.Session) (*response, error) {
    define(
    author("Tony"),
    description("Hello, World"),
    method("GET"),
    since("1.0.1"),
    )

    // 具体的业务逻辑
    }
    ```

    根据方法名自动注册路由,也可以自动生成 API 文档和 Postman,不过暂时还没开源出来。只是表达一个写法哈哈哈。
    xxjwxc
        6
    xxjwxc  
    OP
       2019-12-11 00:22:34 +08:00
    @Trim21 是的。
    xxjwxc
        7
    xxjwxc  
    OP
       2019-12-11 00:25:14 +08:00
    @cuberlzy 哈哈,欢迎开源,欢迎共享。其实我也有考虑返回一个 obj。但是最后去掉了原因是。有时候我们可能返回多种类型,或者多个不确定值。这样局限性比较大了。不过我绝对我可以做一个可以带返回值的也可以不带返回值的。这样会好点。API 文档跟 Postman 正在测试阶段。哈哈很快开出来。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5288 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 01:26 · PVG 09:26 · LAX 18:26 · JFK 21:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.