Skip to content

Commit

Permalink
mixed bindings.
Browse files Browse the repository at this point in the history
supported tags: json , form , uri ,header.
  • Loading branch information
yoyofx committed Nov 12, 2021
1 parent 2661c29 commit d6ed0ce
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 33 deletions.
20 changes: 11 additions & 9 deletions examples/simpleweb/contollers/usercontroller.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package contollers

import (
"fmt"
"github.com/yoyofx/yoyogo/abstractions/servicediscovery"
"github.com/yoyofx/yoyogo/web/actionresult"
"github.com/yoyofx/yoyogo/web/binding"
Expand All @@ -23,22 +22,25 @@ func NewUserController(userAction models.IUserAction, sd servicediscovery.IServi
}

type RegisterRequest struct {
//mvc.RequestBody
UserName string `param:"UserName"`
Password string `param:"Password"`
mvc.RequestBody `route:"/{id}/{tenant}"`

UserName string `uri:"userName"`
Password string `uri:"password"`
}

func (controller UserController) Register(ctx *context.HttpContext, request *RegisterRequest) mvc.ApiResult {
return mvc.ApiResult{Success: true, Message: "ok", Data: request}
}

func (controller UserController) GetUserName(ctx *context.HttpContext, request *RegisterRequest) actionresult.IActionResult {
result := mvc.ApiResult{Success: true, Message: "ok", Data: request}
fmt.Println("hello world")
return actionresult.Json{Data: result}
type PostUserInfoRequest struct {
mvc.RequestBody //`route:"/{id}"`

UserName string `form:"userName" json:"userName"`
Password string `form:"password" json:"password"`
Token string `header:"Authorization" json:"token"`
}

func (controller UserController) PostUserInfo(ctx *context.HttpContext, request *RegisterRequest) actionresult.IActionResult {
func (controller UserController) PostUserInfo(ctx *context.HttpContext, request *PostUserInfoRequest) actionresult.IActionResult {
return actionresult.Json{Data: mvc.ApiResult{Success: true, Message: "ok", Data: context.H{
"user": ctx.GetUser(),
"request": request,
Expand Down
2 changes: 1 addition & 1 deletion web/binding/query_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func (queryBinding) Name() string {
func (queryBinding) Bind(req *http.Request, obj interface{}) error {
values := req.URL.Query()
fmt.Println(values)
if err := mapForm(obj, values); err != nil {
if err := mapUri(obj, values); err != nil {
return err
}
return validate(obj)
Expand Down
42 changes: 26 additions & 16 deletions web/mvc/action_method_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,34 @@ func requestParamTypeConvertFunc(index int, parameter reflectx.MethodParameterIn
paramType = paramType.Elem()
}
if paramType.Kind() == reflect.Struct {
// Mapping -> parameter.Name , paramType.Name() ,paramType, ctx

switch paramType.Name() {
case "HttpContext":
value = reflect.ValueOf(ctx)
default:
reqBindingData := reflect.New(paramType).Interface()
if paramType.NumField() > 0 && paramType.Field(0).Name == "RequestBody" {
bindErr := ctx.Bind(reqBindingData)
if bindErr != nil {
panic(bindErr)
}
} else {
err = errors.New("Can't bind non mvc.RequestBody!")
}
value = reflect.ValueOf(reqBindingData)
// Mapping * struct type -> parameter.Name , paramType.Name() ,paramType, ctx
mappingFunc, hasMapping := RequestMppingFuncs[paramType.Name()]
if hasMapping {
value, err = mappingFunc(parameter.Name, paramType.Name(), paramType, ctx)
} else {
value, err = RequestMppingFuncs["Default"](parameter.Name, paramType.Name(), paramType, ctx)
}

//switch paramType.Name() {
//case "HttpContext":
// value = reflect.ValueOf(ctx)
//default:
// reqBindingData := reflect.New(paramType).Interface()
// if paramType.NumField() > 0 && paramType.Field(0).Name == "RequestBody" {
// bindErr := ctx.Bind(reqBindingData)
// bindErr2:= ctx.BindWith(reqBindingData, binding.Query)
// if bindErr != nil || bindErr2!=nil {
// panic(bindErr.Error() + bindErr2.Error())
// }
// } else {
// err = errors.New("Can't bind non mvc.RequestBody!")
// }
// value = reflect.ValueOf(reqBindingData)
//}
return value, err
} else {
// normal type , such as int ,string, float
}

return value, errors.New("the type not support")
}
37 changes: 30 additions & 7 deletions web/mvc/action_parameters_mapping_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ package mvc

import (
"errors"
"github.com/yoyofx/yoyogo/web/binding"
"github.com/yoyofx/yoyogo/web/context"
"reflect"
)

type ActionParametersMappingFunc interface {
Mapping(paramName string, paramTypeName string, paramType reflect.Type, sourceContext *context.HttpContext) (reflect.Value, error)
var RequestMppingFuncs map[string]ActionParametersMappingFunc = map[string]ActionParametersMappingFunc{
"HttpContext": httpContextMappingMapping,
"Default": requestBodyMappingMapping,
}

type httpContextMapping struct{}
type ActionParametersMappingFunc func(paramName string, paramTypeName string, paramType reflect.Type, sourceContext *context.HttpContext) (reflect.Value, error)

func (mapping httpContextMapping) Mapping(paramName string, paramTypeName string, paramType reflect.Type, sourceContext *context.HttpContext) (reflect.Value, error) {
func httpContextMappingMapping(paramName string, paramTypeName string, paramType reflect.Type, sourceContext *context.HttpContext) (reflect.Value, error) {
var value reflect.Value
var err error
if paramTypeName == "HttpContext" {
Expand All @@ -23,14 +25,35 @@ func (mapping httpContextMapping) Mapping(paramName string, paramTypeName string
return value, err
}

type requestBodyMapping struct{}

func (mapping requestBodyMapping) Mapping(paramName string, paramTypeName string, paramType reflect.Type, sourceContext *context.HttpContext) (reflect.Value, error) {
/**
绑定
form-data/multipart-form , json , uri , header
tags: json , form , uri ,header
*/
func requestBodyMappingMapping(paramName string, paramTypeName string, paramType reflect.Type, sourceContext *context.HttpContext) (reflect.Value, error) {
var value reflect.Value
var err error
reqBindingData := reflect.New(paramType).Interface()

fmTags := map[string]bool{"header": false, "uri": false}
for fi := 0; fi < paramType.NumField(); fi++ {
for key, _ := range fmTags {
_, inTag := paramType.Field(fi).Tag.Lookup(key)
if inTag {
fmTags[key] = inTag
continue
}
}
}

if paramType.NumField() > 0 && paramType.Field(0).Name == "RequestBody" {
err = sourceContext.Bind(reqBindingData)
if fmTags["uri"] {
_ = sourceContext.BindWith(reqBindingData, binding.Query)
} else if fmTags["header"] {
_ = sourceContext.BindWith(reqBindingData, binding.Header)
}

} else {
err = errors.New("Can't bind non mvc.RequestBody!")
}
Expand Down

0 comments on commit d6ed0ce

Please sign in to comment.