gin handler wrapper
This commit is contained in:
parent
5e02216d65
commit
b50bd2c776
|
|
@ -1,8 +1,14 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func UnnamedPointer[T any](v T) *T {
|
||||
|
|
@ -28,3 +34,104 @@ func GinErrorCheck(c *gin.Context, err error) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func setValue(data string, value reflect.Value) error {
|
||||
switch value.Kind() {
|
||||
case reflect.Bool:
|
||||
break
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v, err := strconv.ParseInt(data, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value.SetInt(int64(v))
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v, err := strconv.ParseUint(data, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value.SetUint(v)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
v, err := strconv.ParseFloat(data, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value.SetFloat(v)
|
||||
case reflect.Pointer:
|
||||
return setValue(data, reflect.Indirect(value))
|
||||
case reflect.String:
|
||||
value.SetString(data)
|
||||
case reflect.Struct:
|
||||
err := json.Unmarshal([]byte(data), value.Pointer())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
log.Errorf("utils.setValue unsupported type %s", value.Type().Name())
|
||||
return errors.New("unsupported type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func routeWrapperHandler(handler any, names []string) func(ctx *gin.Context) {
|
||||
return func(c *gin.Context) {
|
||||
handlerFunc := reflect.ValueOf(handler)
|
||||
handlerFuncType := handlerFunc.Type()
|
||||
handlerFuncParamLen := handlerFuncType.NumIn()
|
||||
if handlerFuncParamLen != len(names) {
|
||||
panic("Handler func Param len != len(names)")
|
||||
}
|
||||
inputArgs := make([]reflect.Value, handlerFuncParamLen)
|
||||
for i := 0; i < handlerFuncParamLen; i += 1 {
|
||||
paraType := handlerFuncType.In(i)
|
||||
var paraValue reflect.Value
|
||||
if paraType.Kind() == reflect.Pointer {
|
||||
paraValue = reflect.New(paraType.Elem())
|
||||
} else {
|
||||
paraValue = reflect.New(paraType)
|
||||
}
|
||||
v, ok := c.Get(names[i])
|
||||
if ok {
|
||||
paraValue.Set(reflect.ValueOf(v))
|
||||
} else {
|
||||
vs := c.Param(names[i])
|
||||
if vs == "" {
|
||||
vs = c.Query(names[i])
|
||||
}
|
||||
if vs != "" {
|
||||
err := setValue(vs, paraValue)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Cannot set value")
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if paraValue.Kind() == reflect.Struct || (paraType.Kind() == reflect.Pointer && paraType.Elem().Kind() == reflect.Struct) {
|
||||
err := c.BindJSON(paraValue.Interface())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"ok": false,
|
||||
"msg": fmt.Sprintf("Cannot BindJson %s: %s", paraType.Name(), err.Error())})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if paraType.Kind() == reflect.Pointer {
|
||||
inputArgs[i] = paraValue
|
||||
} else {
|
||||
inputArgs[i] = paraValue.Elem()
|
||||
}
|
||||
}
|
||||
out := handlerFunc.Call(inputArgs)
|
||||
var ret = out[0].Interface()
|
||||
if out[1].Interface() != nil {
|
||||
var err = out[1].Interface().(error)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"ok": false, "msg": err.Error()})
|
||||
} else {
|
||||
c.JSON(http.StatusOK, ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func RouteWrapper(r *gin.Engine, method string, route string, handler any, names []string) {
|
||||
r.Handle(method, route, routeWrapperHandler(handler, names))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"k8s-manager/src/model"
|
||||
"k8s-manager/src/utils"
|
||||
)
|
||||
|
||||
func DataHandler(model model.DataModel, q1 string, q2 int) (map[string]any, error) {
|
||||
s, _ := json.Marshal(model)
|
||||
fmt.Println(string(s))
|
||||
fmt.Printf("Call DataHandler %s %d\n", q1, q2)
|
||||
return gin.H{"name": model.Name}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
r := gin.Default()
|
||||
utils.RouteWrapper(r, "GET", "/index", DataHandler, []string{"model", "q1", "q2"})
|
||||
err := r.Run(":9000")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue