golang Gin参数自动绑定与RPC工具插件库Ginrpc的使用

Golang Gin 参数自动绑定与 RPC 工具插件库 Ginrpc 的使用

Ginrpc 是一个基于 Go-Gin 框架的自动参数绑定和 RPC 工具库,支持多种接口模式和注解路由等功能。

主要特性

  • 支持 RPC 自动映射
  • 支持对象注册
  • 支持注解路由
  • 基于 Go-Gin 框架的 JSON RESTful 风格
  • 实现参数过滤和请求绑定
  • 代码注册简单,支持多种注册方式
  • 支持 grpc-go 绑定
  • 支持 Swagger 文档生成
  • 支持 Markdown/Mindoc 文档生成
  • 支持前后调用中间件

安装

使用 go mod 安装:

go get -u github.com/xxjwxc/ginrpc@master

API 详情

支持的三种接口模式

  1. 原始 Gin 接口模式:

    func(*gin.Context)
    
  2. 自定义上下文类型:

    func(*api.Context)
    func(*api.Context, req)
    func(*api.Context, *req)
    
  3. Gin 上下文与请求参数:

    func(*gin.Context, *req)
    func(*gin.Context, req)
    func(*gin.Context, *req)(*resp, error) // grpc-go 风格
    func(*gin.Context, req)(resp, error)
    

示例代码

1. 参数自动绑定与对象注册(注解路由)

package main

import (
	"fmt"
	"net/http"

	_ "gmsec/routers" // Debug 模式需要添加 [mod]/routers 注册注解路由
	"github.com/xxjwxc/public/mydoc/myswagger" // swagger 支持

	"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)
	c.JSON(http.StatusOK, "ok")
}

// Hello2 不带注解的路由 (参数为 2 默认 post)
func (s *Hello) Hello2(c *gin.Context, req ReqTest) {
	fmt.Println(req)
	c.JSON(http.StatusOK, "ok")
}

// [grpc-go](https://github.com/grpc/grpc-go)
// 带请求参数、返回值和错误
// TestFun6 不带注解的路由 (参数为 2 默认 post)
func TestFun6(c *gin.Context, req ReqTest) (*ReqTest, error) {
	fmt.Println(req)
	return &req, nil
}

func main() {
	// swagger 配置
	myswagger.SetHost("https://localhost:8080")
	myswagger.SetBasePath("gmsec")
	myswagger.SetSchemes(true, false)
	// -----end --
	
	base := ginrpc.New()
	router := gin.Default() // 或 router := gin.Default().Group("/xxjwxc")
	
	// 对象注册 (类似 go-micro)
	base.Register(router, new(Hello)) 
	
	// 函数注册
	router.POST("/test6", base.HandlerFunc(TestFun6))                            
	base.RegisterHandlerFunc(router, []string{"post", "get"}, "/test", TestFun6) 
	
	router.Run(":8080")
}

注解路由说明

// @Router /block [post,get]
  • @Router 标签
  • /block 路由路径
  • [post,get] 支持的 HTTP 方法

注意:如果对象函数中没有注解路由,系统会默认添加注解路由。POST 模式需要 2 个参数 (ctx, req),GET 模式只需要 1 个参数 (ctx)。

参数说明

ginrpc.WithCtx // 设置自定义上下文
ginrpc.WithDebug(true) // 设置调试模式
ginrpc.WithOutDoc(true) // 输出 Markdown/Swagger API 文档
ginrpc.WithBigCamel(true) // 设置大驼峰标准 (false 为 web 模式,_,小写)
ginrpc.WithBeforeAfter(&ginrpc.DefaultGinBeforeAfter{}) // 前后调用

测试 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. 支持对象注册 ginrpc.Register 模式的文档导出

2. 导出支持注解路由、参数注解和默认值 (tag 'default')

3. 默认导出路径

  • /docs/swagger/swagger.json
  • /docs/markdown

4. 结构体示例

type ReqTest struct {
	AccessToken string `json:"access_token"`
	UserName    string `json:"user_name" binding:"required"` // 带校验方式
	Password    string `json:"password"`
}

中间件支持

使用 ginrpc.WithBeforeAfter(&ginrpc.DefaultGinBeforeAfter{})

也可以实现对象上的函数(单一类型):

// GinBeforeAfter 在对象调用前后执行中间件(支持从对象中单独添加对象)
type GinBeforeAfter interface {
	GinBefore(req *GinBeforeAfterInfo) bool
	GinAfter(req *GinBeforeAfterInfo) bool
}

这是一个功能强大的 Gin 扩展库,可以大大简化 API 开发流程,提高开发效率。


更多关于golang Gin参数自动绑定与RPC工具插件库Ginrpc的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang Gin参数自动绑定与RPC工具插件库Ginrpc的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang Gin参数自动绑定与RPC工具插件库Ginrpc

Gin参数自动绑定

Gin框架提供了强大的参数绑定功能,可以自动将HTTP请求中的参数绑定到结构体上。以下是Gin参数绑定的几种常见方式:

1. ShouldBind系列方法

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

type LoginForm struct {
	Username string `form:"username" json:"username" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

func main() {
	r := gin.Default()
	
	r.POST("/login", func(c *gin.Context) {
		var form LoginForm
		
		// 根据Content-Type自动选择绑定方式
		if err := c.ShouldBind(&form); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		
		// 特定绑定方式
		// c.ShouldBindJSON(&form)  // 只绑定JSON
		// c.ShouldBindQuery(&form) // 只绑定查询参数
		// c.ShouldBindUri(&form)   // 只绑定URI参数
		
		c.JSON(http.StatusOK, gin.H{"status": "logged in"})
	})
	
	r.Run(":8080")
}

2. 自定义绑定器

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

type Booking struct {
	CheckIn  time.Time `form:"check_in" binding:"required" time_format:"2006-01-02"`
	CheckOut time.Time `form:"check_out" binding:"required" time_format:"2006-01-02"`
}

func main() {
	r := gin.Default()
	
	r.GET("/bookable", func(c *gin.Context) {
		var booking Booking
		if err := c.ShouldBind(&booking); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		
		c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
	})
	
	r.Run(":8080")
}

Ginrpc RPC工具插件库

Ginrpc是一个基于Gin框架的RPC插件库,它可以帮助开发者快速构建RESTful API服务,支持自动路由注册、参数绑定、中间件等功能。

Ginrpc基本使用

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/xxjwxc/ginrpc"
	"github.com/xxjwxc/ginrpc/api"
	"net/http"
)

// @Router /api/v1/hello [get]
type HelloReq struct {
	Name string `form:"name" json:"name"` // 参数
}

// Hello 方法注释
func Hello(c *gin.Context, req *HelloReq) (*api.Response, error) {
	return &api.Response{
		Result: "hello " + req.Name,
	}, nil
}

func main() {
	base := gin.Default()
	
	// 注册路由
	router := ginrpc.New(base, ginrpc.WithCtx(func(c *gin.Context) interface{} {
		return c
	})
	
	// 注册handler
	router.Register(&Hello{})
	
	base.Run(":8080")
}

Ginrpc高级特性

  1. 自动生成Swagger文档
router := ginrpc.New(base, 
	ginrpc.WithCtx(func(c *gin.Context) interface{} {
		return c
	}),
	ginrpc.WithOutDoc(true), // 开启文档生成
	ginrpc.WithOutPath("swagger"), // 文档输出路径
)
  1. 中间件支持
func Middleware(c *gin.Context) {
	// 中间件逻辑
	c.Next()
}

router := ginrpc.New(base, 
	ginrpc.WithCtx(func(c *gin.Context) interface{} {
		return c
	}),
	ginrpc.WithMiddleware(Middleware),
)
  1. 自定义响应格式
type CustomResponse struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

func Response(c *gin.Context, resp *CustomResponse) {
	c.JSON(http.StatusOK, resp)
}

router := ginrpc.New(base, 
	ginrpc.WithCtx(func(c *gin.Context) interface{} {
		return c
	}),
	ginrpc.WithResponse(Response),
)

Ginrpc参数绑定示例

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/xxjwxc/ginrpc"
	"github.com/xxjwxc/ginrpc/api"
	"net/http"
	"time"
)

// UserInfo 用户信息
type UserInfo struct {
	ID        int       `json:"id"`         // 用户ID
	Name      string    `json:"name"`       // 用户名
	Birthday  time.Time `json:"birthday"`   // 生日
	CreatedAt time.Time `json:"created_at"` // 创建时间
}

// GetUserReq 获取用户请求参数
type GetUserReq struct {
	ID int `uri:"id" binding:"required"` // 用户ID
}

// GetUser 获取用户信息
func GetUser(c *gin.Context, req *GetUserReq) (*api.Response, error) {
	// 模拟从数据库获取用户信息
	user := UserInfo{
		ID:        req.ID,
		Name:      "张三",
		Birthday:  time.Date(1990, 1, 1, 0, 0, 0, 0, time.UTC),
		CreatedAt: time.Now(),
	}
	
	return &api.Response{
		Result: user,
	}, nil
}

func main() {
	base := gin.Default()
	
	router := ginrpc.New(base, ginrpc.WithCtx(func(c *gin.Context) interface{} {
		return c
	}))
	
	router.Register(&GetUser{})
	
	base.Run(":8080")
}

总结

  1. Gin框架提供了强大的参数绑定功能,可以自动将请求参数绑定到结构体
  2. Ginrpc是基于Gin的RPC插件库,简化了API开发流程
  3. Ginrpc支持自动路由注册、参数绑定、中间件、Swagger文档生成等功能
  4. 通过Ginrpc可以快速构建规范的RESTful API服务

对于需要快速开发API服务的项目,Ginrpc是一个不错的选择,它结合了Gin的高性能和RPC的便捷性,能够显著提高开发效率。

回到顶部