mirror of
https://github.com/xxjwxc/ginrpc.git
synced 2025-10-05 23:16:53 +08:00
add middleware
支持调用中间件
This commit is contained in:
13
README.md
13
README.md
@@ -162,6 +162,8 @@ func main() {
|
|||||||
|
|
||||||
ginrpc.WithBigCamel(true) : Set big camel standard (false is web mode, _, lowercase)
|
ginrpc.WithBigCamel(true) : Set big camel standard (false is web mode, _, lowercase)
|
||||||
|
|
||||||
|
ginrpc.WithBeforeAfter(&ginrpc.DefaultGinBeforeAfter{}) : Before After call
|
||||||
|
|
||||||
[more>>](https://godoc.org/github.com/xxjwxc/ginrpc)
|
[more>>](https://godoc.org/github.com/xxjwxc/ginrpc)
|
||||||
|
|
||||||
### 4. Execute curl to automatically bind parameters. See the results directly
|
### 4. Execute curl to automatically bind parameters. See the results directly
|
||||||
@@ -189,6 +191,17 @@ type ReqTest struct {
|
|||||||
```
|
```
|
||||||
- [more >>>](https://github.com/xxjwxc/gmsec)
|
- [more >>>](https://github.com/xxjwxc/gmsec)
|
||||||
|
|
||||||
|
## 三. Support to call Middleware
|
||||||
|
- using `ginrpc.WithBeforeAfter(&ginrpc.DefaultGinBeforeAfter{})`
|
||||||
|
- You can also implement functions (single types) on objects
|
||||||
|
```go
|
||||||
|
// GinBeforeAfter Execute middleware before and after the object call (support adding the object separately from the object in total)
|
||||||
|
type GinBeforeAfter interface {
|
||||||
|
GinBefore(req *GinBeforeAfterInfo) bool
|
||||||
|
GinAfter(req *GinBeforeAfterInfo) bool
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Stargazers over time
|
## Stargazers over time
|
||||||
|
|
||||||
[](https://starchart.cc/xxjwxc/ginrpc)
|
[](https://starchart.cc/xxjwxc/ginrpc)
|
||||||
|
12
README_cn.md
12
README_cn.md
@@ -159,6 +159,8 @@ _ "[mod]/routers" // debug模式需要添加[mod]/routers 注册注解路由
|
|||||||
|
|
||||||
ginrpc.WithBigCamel(true) : 设置大驼峰标准(false 为web模式,_,小写)
|
ginrpc.WithBigCamel(true) : 设置大驼峰标准(false 为web模式,_,小写)
|
||||||
|
|
||||||
|
ginrpc.WithBeforeAfter(&ginrpc.DefaultGinBeforeAfter{}) : 设置调用前后执行中间件
|
||||||
|
|
||||||
[更多>>](https://godoc.org/github.com/xxjwxc/ginrpc)
|
[更多>>](https://godoc.org/github.com/xxjwxc/ginrpc)
|
||||||
|
|
||||||
### 2. 注解路由调用demo:[gmsec](https://github.com/gmsec/gmsec)
|
### 2. 注解路由调用demo:[gmsec](https://github.com/gmsec/gmsec)
|
||||||
@@ -181,6 +183,16 @@ type ReqTest struct {
|
|||||||
|
|
||||||
- [更多 >>>](https://github.com/xxjwxc/gmsec)
|
- [更多 >>>](https://github.com/xxjwxc/gmsec)
|
||||||
|
|
||||||
|
## 三. 支持调用中间件
|
||||||
|
- 可通过 `ginrpc.WithBeforeAfter(&ginrpc.DefaultGinBeforeAfter{})`设置(全局)
|
||||||
|
- 也可以在对象上实现函数(单个类型)
|
||||||
|
```go
|
||||||
|
// GinBeforeAfter 对象调用前后执行中间件(支持总的跟对象单独添加)
|
||||||
|
type GinBeforeAfter interface {
|
||||||
|
GinBefore(req *GinBeforeAfterInfo) bool
|
||||||
|
GinAfter(req *GinBeforeAfterInfo) bool
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Stargazers over time
|
## Stargazers over time
|
||||||
|
|
||||||
|
184
common.go
184
common.go
@@ -1,6 +1,7 @@
|
|||||||
package ginrpc
|
package ginrpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
@@ -54,7 +55,7 @@ func (b *_Base) checkHandlerFunc(typ reflect.Type, isObj bool) (int, bool) { //
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HandlerFunc Get and filter the parameters to be bound (object call type)
|
// HandlerFunc Get and filter the parameters to be bound (object call type)
|
||||||
func (b *_Base) handlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { // 获取并过滤要绑定的参数(obj 对象类型)
|
func (b *_Base) handlerFuncObj(tvl, obj reflect.Value, methodName string) gin.HandlerFunc { // 获取并过滤要绑定的参数(obj 对象类型)
|
||||||
typ := tvl.Type()
|
typ := tvl.Type()
|
||||||
if typ.NumIn() == 2 { // Parameter checking 参数检查
|
if typ.NumIn() == 2 { // Parameter checking 参数检查
|
||||||
ctxType := typ.In(1)
|
ctxType := typ.In(1)
|
||||||
@@ -73,7 +74,7 @@ func (b *_Base) handlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { // 获
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Custom context type with request parameters .自定义的context类型,带request 请求参数
|
// Custom context type with request parameters .自定义的context类型,带request 请求参数
|
||||||
call, err := b.getCallFunc3(tvl, obj)
|
call, err := b.getCallObj3(tvl, obj, methodName)
|
||||||
if err != nil { // Direct reporting error.
|
if err != nil { // Direct reporting error.
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -81,16 +82,39 @@ func (b *_Base) handlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { // 获
|
|||||||
return call
|
return call
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom context type with request parameters
|
func (b *_Base) beforCall(c *gin.Context, tvl, obj reflect.Value, req interface{}, methodName string) (*GinBeforeAfterInfo, bool) {
|
||||||
func (b *_Base) getCallFunc3(tvls ...reflect.Value) (func(*gin.Context), error) {
|
info := &GinBeforeAfterInfo{
|
||||||
offset := 0
|
C: c,
|
||||||
if len(tvls) > 1 {
|
FuncName: fmt.Sprintf("%v.%v", reflect.Indirect(obj).Type().Name(), methodName), // 函数名
|
||||||
offset = 1
|
Req: req, // 调用前的请求参数
|
||||||
|
Context: context.Background(), // 占位参数,可用于存储其他参数,前后连接可用
|
||||||
}
|
}
|
||||||
|
|
||||||
tvl := tvls[0]
|
is := true
|
||||||
|
if bfobj, ok := obj.Interface().(GinBeforeAfter); ok { // 本类型
|
||||||
|
is = bfobj.GinBefore(info)
|
||||||
|
}
|
||||||
|
if is && b.beforeAfter != nil {
|
||||||
|
is = b.beforeAfter.GinBefore(info)
|
||||||
|
}
|
||||||
|
return info, is
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *_Base) afterCall(info *GinBeforeAfterInfo, obj reflect.Value) bool {
|
||||||
|
is := true
|
||||||
|
if bfobj, ok := obj.Interface().(GinBeforeAfter); ok { // 本类型
|
||||||
|
is = bfobj.GinAfter(info)
|
||||||
|
}
|
||||||
|
if is && b.beforeAfter != nil {
|
||||||
|
is = b.beforeAfter.GinAfter(info)
|
||||||
|
}
|
||||||
|
return is
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom context type with request parameters
|
||||||
|
func (b *_Base) getCallFunc3(tvl reflect.Value) (func(*gin.Context), error) {
|
||||||
typ := tvl.Type()
|
typ := tvl.Type()
|
||||||
if typ.NumIn() != (2 + offset) { // Parameter checking 参数检查
|
if typ.NumIn() != 2 { // Parameter checking 参数检查
|
||||||
return nil, errors.New("method " + runtime.FuncForPC(tvl.Pointer()).Name() + " not support!")
|
return nil, errors.New("method " + runtime.FuncForPC(tvl.Pointer()).Name() + " not support!")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +129,7 @@ func (b *_Base) getCallFunc3(tvls ...reflect.Value) (func(*gin.Context), error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxType, reqType := typ.In(0+offset), typ.In(1+offset)
|
ctxType, reqType := typ.In(0), typ.In(1)
|
||||||
|
|
||||||
reqIsGinCtx := false
|
reqIsGinCtx := false
|
||||||
if ctxType == reflect.TypeOf(&gin.Context{}) {
|
if ctxType == reflect.TypeOf(&gin.Context{}) {
|
||||||
@@ -129,12 +153,115 @@ func (b *_Base) getCallFunc3(tvls ...reflect.Value) (func(*gin.Context), error)
|
|||||||
|
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
req := reflect.New(reqType)
|
req := reflect.New(reqType)
|
||||||
if reqIsValue {
|
if !reqIsValue {
|
||||||
req = reflect.New(reqType)
|
|
||||||
} else {
|
|
||||||
req = reflect.New(reqType.Elem())
|
req = reflect.New(reqType.Elem())
|
||||||
}
|
}
|
||||||
if err := b.unmarshal(c, req.Interface()); err != nil { // Return error message.返回错误信息
|
if err := b.unmarshal(c, req.Interface()); err != nil { // Return error message.返回错误信息
|
||||||
|
b.handErrorString(c, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if reqIsValue {
|
||||||
|
req = req.Elem()
|
||||||
|
}
|
||||||
|
var returnValues []reflect.Value
|
||||||
|
returnValues = tvl.Call([]reflect.Value{reflect.ValueOf(apiFun(c)), req})
|
||||||
|
|
||||||
|
if returnValues != nil {
|
||||||
|
obj := returnValues[0].Interface()
|
||||||
|
rerr := returnValues[1].Interface()
|
||||||
|
if rerr != nil {
|
||||||
|
msg := message.GetErrorMsg(message.InValidOp)
|
||||||
|
msg.Error = rerr.(error).Error()
|
||||||
|
c.JSON(http.StatusBadRequest, msg)
|
||||||
|
} else {
|
||||||
|
c.JSON(http.StatusOK, obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom context type with request parameters
|
||||||
|
func (b *_Base) getCallObj3(tvl, obj reflect.Value, methodName string) (func(*gin.Context), error) {
|
||||||
|
typ := tvl.Type()
|
||||||
|
if typ.NumIn() != 3 { // Parameter checking 参数检查
|
||||||
|
return nil, errors.New("method " + runtime.FuncForPC(tvl.Pointer()).Name() + " not support!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if typ.NumOut() != 0 {
|
||||||
|
if typ.NumOut() == 2 { // Parameter checking 参数检查
|
||||||
|
if returnType := typ.Out(1); returnType != typeOfError {
|
||||||
|
return nil, errors.Errorf("method : %v , returns[1] %v not error",
|
||||||
|
runtime.FuncForPC(tvl.Pointer()).Name(), returnType.String())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("method : %v , Only 2 return values (obj, error) are supported", runtime.FuncForPC(tvl.Pointer()).Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxType, reqType := typ.In(1), typ.In(2)
|
||||||
|
|
||||||
|
reqIsGinCtx := false
|
||||||
|
if ctxType == reflect.TypeOf(&gin.Context{}) {
|
||||||
|
reqIsGinCtx = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ctxType != reflect.TypeOf(gin.Context{}) &&
|
||||||
|
// ctxType != reflect.Indirect(reflect.ValueOf(b.iAPIType)).Type()
|
||||||
|
if !reqIsGinCtx && ctxType != b.apiType && !b.apiType.ConvertibleTo(ctxType) {
|
||||||
|
return nil, errors.New("method " + runtime.FuncForPC(tvl.Pointer()).Name() + " first parm not support!")
|
||||||
|
}
|
||||||
|
|
||||||
|
reqIsValue := true
|
||||||
|
if reqType.Kind() == reflect.Ptr {
|
||||||
|
reqIsValue = false
|
||||||
|
}
|
||||||
|
apiFun := func(c *gin.Context) interface{} { return c }
|
||||||
|
if !reqIsGinCtx {
|
||||||
|
apiFun = b.apiFun
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
req := reflect.New(reqType)
|
||||||
|
if !reqIsValue {
|
||||||
|
req = reflect.New(reqType.Elem())
|
||||||
|
}
|
||||||
|
if err := b.unmarshal(c, req.Interface()); err != nil { // Return error message.返回错误信息
|
||||||
|
b.handErrorString(c, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if reqIsValue {
|
||||||
|
req = req.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
bainfo, is := b.beforCall(c, tvl, obj, req.Interface(), methodName)
|
||||||
|
if !is {
|
||||||
|
c.JSON(http.StatusBadRequest, bainfo.Resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var returnValues []reflect.Value
|
||||||
|
returnValues = tvl.Call([]reflect.Value{obj, reflect.ValueOf(apiFun(c)), req})
|
||||||
|
|
||||||
|
if returnValues != nil {
|
||||||
|
bainfo.Resp = returnValues[0].Interface()
|
||||||
|
rerr := returnValues[1].Interface()
|
||||||
|
if rerr != nil {
|
||||||
|
bainfo.Error = rerr.(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
is = b.afterCall(bainfo, obj)
|
||||||
|
if is {
|
||||||
|
c.JSON(http.StatusOK, bainfo.Resp)
|
||||||
|
} else {
|
||||||
|
c.JSON(http.StatusBadRequest, bainfo.Resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *_Base) handErrorString(c *gin.Context, req reflect.Value, err error) {
|
||||||
var fields []string
|
var fields []string
|
||||||
if _, ok := err.(validator.ValidationErrors); ok {
|
if _, ok := err.(validator.ValidationErrors); ok {
|
||||||
for _, err := range err.(validator.ValidationErrors) {
|
for _, err := range err.(validator.ValidationErrors) {
|
||||||
@@ -168,29 +295,6 @@ func (b *_Base) getCallFunc3(tvls ...reflect.Value) (func(*gin.Context), error)
|
|||||||
msg.Error = fmt.Sprintf("req param : %v", strings.Join(fields, ";"))
|
msg.Error = fmt.Sprintf("req param : %v", strings.Join(fields, ";"))
|
||||||
c.JSON(http.StatusBadRequest, msg)
|
c.JSON(http.StatusBadRequest, msg)
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
|
||||||
if reqIsValue {
|
|
||||||
req = req.Elem()
|
|
||||||
}
|
|
||||||
var returnValues []reflect.Value
|
|
||||||
if offset > 0 {
|
|
||||||
returnValues = tvl.Call([]reflect.Value{tvls[1], reflect.ValueOf(apiFun(c)), req})
|
|
||||||
} else {
|
|
||||||
returnValues = tvl.Call([]reflect.Value{reflect.ValueOf(apiFun(c)), req})
|
|
||||||
}
|
|
||||||
if returnValues != nil {
|
|
||||||
obj := returnValues[0].Interface()
|
|
||||||
rerr := returnValues[1].Interface()
|
|
||||||
if rerr != nil {
|
|
||||||
msg := message.GetErrorMsg(message.InValidOp)
|
|
||||||
msg.Error = rerr.(error).Error()
|
|
||||||
c.JSON(http.StatusBadRequest, msg)
|
|
||||||
} else {
|
|
||||||
c.JSON(http.StatusOK, obj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *_Base) unmarshal(c *gin.Context, v interface{}) error {
|
func (b *_Base) unmarshal(c *gin.Context, v interface{}) error {
|
||||||
@@ -400,11 +504,11 @@ func (b *_Base) register(router gin.IRouter, cList ...interface{}) bool {
|
|||||||
if _b {
|
if _b {
|
||||||
if v, ok := mp[objName+"."+method.Name]; ok {
|
if v, ok := mp[objName+"."+method.Name]; ok {
|
||||||
for _, v1 := range v {
|
for _, v1 := range v {
|
||||||
b.registerHandlerObj(router, v1.GenComment.Methods, v1.GenComment.RouterPath, method.Func, refVal)
|
b.registerHandlerObj(router, v1.GenComment.Methods, v1.GenComment.RouterPath, method.Name, method.Func, refVal)
|
||||||
}
|
}
|
||||||
} else { // not find using default case
|
} else { // not find using default case
|
||||||
routerPath, methods := b.getDefaultComments(objName, method.Name, num)
|
routerPath, methods := b.getDefaultComments(objName, method.Name, num)
|
||||||
b.registerHandlerObj(router, methods, routerPath, method.Func, refVal)
|
b.registerHandlerObj(router, methods, routerPath, method.Name, method.Func, refVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -428,8 +532,8 @@ func (b *_Base) getDefaultComments(objName, objFunc string, num int) (routerPath
|
|||||||
}
|
}
|
||||||
|
|
||||||
// registerHandlerObj Multiple registration methods.获取并过滤要绑定的参数
|
// registerHandlerObj Multiple registration methods.获取并过滤要绑定的参数
|
||||||
func (b *_Base) registerHandlerObj(router gin.IRouter, httpMethod []string, relativePath string, tvl, obj reflect.Value) error {
|
func (b *_Base) registerHandlerObj(router gin.IRouter, httpMethod []string, relativePath, methodName string, tvl, obj reflect.Value) error {
|
||||||
call := b.handlerFuncObj(tvl, obj)
|
call := b.handlerFuncObj(tvl, obj, methodName)
|
||||||
|
|
||||||
for _, v := range httpMethod {
|
for _, v := range httpMethod {
|
||||||
// method := strings.ToUpper(v)
|
// method := strings.ToUpper(v)
|
||||||
|
@@ -17,6 +17,7 @@ type _Base struct {
|
|||||||
apiFun NewAPIFunc
|
apiFun NewAPIFunc
|
||||||
apiType reflect.Type
|
apiType reflect.Type
|
||||||
outPath string // output path.输出目录
|
outPath string // output path.输出目录
|
||||||
|
beforeAfter GinBeforeAfter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option overrides behavior of Connect.
|
// Option overrides behavior of Connect.
|
||||||
@@ -61,6 +62,13 @@ func WithBigCamel(b bool) Option {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithBeforeAfter set before and after call.设置对象调用前后执行中间件
|
||||||
|
func WithBeforeAfter(beforeAfter GinBeforeAfter) Option {
|
||||||
|
return optionFunc(func(o *_Base) {
|
||||||
|
o.beforeAfter = beforeAfter
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Default new op obj
|
// Default new op obj
|
||||||
func Default() *_Base {
|
func Default() *_Base {
|
||||||
b := new(_Base)
|
b := new(_Base)
|
||||||
|
2
go.mod
2
go.mod
@@ -5,7 +5,7 @@ go 1.12
|
|||||||
require (
|
require (
|
||||||
github.com/gin-gonic/gin v1.6.3
|
github.com/gin-gonic/gin v1.6.3
|
||||||
github.com/go-playground/validator/v10 v10.2.0
|
github.com/go-playground/validator/v10 v10.2.0
|
||||||
github.com/xxjwxc/public v0.0.0-20200526160023-d8d1bd6babeb
|
github.com/xxjwxc/public v0.0.0-20200601115915-ab2b4ce31a9c
|
||||||
)
|
)
|
||||||
|
|
||||||
// replace github.com/xxjwxc/public => ../public
|
// replace github.com/xxjwxc/public => ../public
|
||||||
|
2
go.sum
2
go.sum
@@ -168,6 +168,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
|
|||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/xxjwxc/public v0.0.0-20200526160023-d8d1bd6babeb h1:tmQZkQGPqTyZ3dLg3ZMhSfXrio69EUpM6i6tJ2yH75w=
|
github.com/xxjwxc/public v0.0.0-20200526160023-d8d1bd6babeb h1:tmQZkQGPqTyZ3dLg3ZMhSfXrio69EUpM6i6tJ2yH75w=
|
||||||
github.com/xxjwxc/public v0.0.0-20200526160023-d8d1bd6babeb/go.mod h1:s1lcFEJl/8sQNC5jYCmmHqwWH/uf2EtMmYoji33ZKQQ=
|
github.com/xxjwxc/public v0.0.0-20200526160023-d8d1bd6babeb/go.mod h1:s1lcFEJl/8sQNC5jYCmmHqwWH/uf2EtMmYoji33ZKQQ=
|
||||||
|
github.com/xxjwxc/public v0.0.0-20200601115915-ab2b4ce31a9c h1:FC1aGStnQOk+H7nztD6LAh2ZY8SODeO0i1Agvrkw1tc=
|
||||||
|
github.com/xxjwxc/public v0.0.0-20200601115915-ab2b4ce31a9c/go.mod h1:s1lcFEJl/8sQNC5jYCmmHqwWH/uf2EtMmYoji33ZKQQ=
|
||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
64
middleware.go
Normal file
64
middleware.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package ginrpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/xxjwxc/public/message"
|
||||||
|
|
||||||
|
"github.com/xxjwxc/public/mylog"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GinBeforeAfterInfo 对象调用前后执行中间件参数
|
||||||
|
type GinBeforeAfterInfo struct {
|
||||||
|
C *gin.Context
|
||||||
|
FuncName string // 函数名
|
||||||
|
Req interface{} // 调用前的请求参数
|
||||||
|
Resp interface{} // 调用后的返回参数
|
||||||
|
Error error
|
||||||
|
// Other options for implementations of the interface
|
||||||
|
// can be stored in a context
|
||||||
|
Context context.Context // 占位参数,可用于存储其他参数,前后连接可用
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GinBeforeAfter 对象调用前后执行中间件(支持总的跟对象单独添加)
|
||||||
|
type GinBeforeAfter interface {
|
||||||
|
GinBefore(req *GinBeforeAfterInfo) bool
|
||||||
|
GinAfter(req *GinBeforeAfterInfo) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultGinBeforeAfter 创建一个默认 BeforeAfter Middleware
|
||||||
|
type DefaultGinBeforeAfter struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type timeTrace struct{}
|
||||||
|
|
||||||
|
// GinBefore call之前调用
|
||||||
|
func (d *DefaultGinBeforeAfter) GinBefore(req *GinBeforeAfterInfo) bool {
|
||||||
|
req.Context = context.WithValue(req.Context, timeTrace{}, time.Now())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// GinAfter call之后调用
|
||||||
|
func (d *DefaultGinBeforeAfter) GinAfter(req *GinBeforeAfterInfo) bool {
|
||||||
|
begin := (req.Context.Value(timeTrace{})).(time.Time)
|
||||||
|
now := time.Now()
|
||||||
|
mylog.Info(fmt.Sprintf("[middleware] call[%v] [%v]", req.FuncName, now.Sub(begin)))
|
||||||
|
// 设置resp 结果
|
||||||
|
if req.Error == nil {
|
||||||
|
msg := message.GetSuccessMsg()
|
||||||
|
msg.Data = req.Resp
|
||||||
|
req.Resp = msg
|
||||||
|
} else {
|
||||||
|
msg := message.GetErrorStrMsg(req.Error.Error())
|
||||||
|
msg.Data = req.Resp
|
||||||
|
req.Resp = msg
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------end
|
Reference in New Issue
Block a user