Skip to content

Commit

Permalink
✨ feat: Structured routing supports PreInvoker
Browse files Browse the repository at this point in the history
  • Loading branch information
sohaha committed Jul 21, 2024
1 parent b7373a4 commit 76c1152
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 41 deletions.
44 changes: 19 additions & 25 deletions znet/bind_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,23 @@ import (
"github.com/sohaha/zlsgo/zutil"
)

var preInvokers = make([]reflect.Type, 0)

// RegisterPreInvoker Register Pre Invoker
func RegisterPreInvoker(invoker ...zdi.PreInvoker) {
loop:
for i := range invoker {
typ := zreflect.TypeOf(invoker[i])
for i := range preInvokers {
if preInvokers[i] == typ {
continue loop
}
}

preInvokers = append(preInvokers, typ)
}
}

// BindStruct Bind Struct
func (e *Engine) BindStruct(prefix string, s interface{}, handle ...Handler) error {
g := e.Group(prefix)
Expand Down Expand Up @@ -40,24 +57,10 @@ func (e *Engine) BindStruct(prefix string, s interface{}, handle ...Handler) err
}
}

preInvokerFn := of.MethodByName("PreInvoker")
var preInvokers []reflect.Type
if preInvokerFn.IsValid() {
before, ok := preInvokerFn.Interface().(func() []zdi.PreInvoker)
if ok {
pres := before()
for i := range pres {
preInvokers = append(preInvokers, reflect.TypeOf(pres[i]))
}
} else {
return fmt.Errorf("func: [%s] is not an effective routing method", "PreInvoker")
}
}

typeOf := reflect.Indirect(of).Type()
return zutil.TryCatch(func() error {
return zreflect.ForEachMethod(of, func(i int, m reflect.Method, value reflect.Value) error {
if m.Name == "Init" || m.Name == "PreInvoker" {
if m.Name == "Init" {
return nil
}
path, method, key := "", "", ""
Expand All @@ -83,16 +86,7 @@ func (e *Engine) BindStruct(prefix string, s interface{}, handle ...Handler) err
method = strings.ToUpper(info[1])
}

var fn interface{}
for i := range preInvokers {
if value.Type().ConvertibleTo(preInvokers[i]) {
fn = value.Convert(preInvokers[i]).Interface()
break
}
}
if fn == nil {
fn = value.Interface()
}
fn := value.Interface()

handleName := strings.Join([]string{typeOf.PkgPath(), typeOf.Name(), m.Name}, ".")
if e.BindStructCase != nil {
Expand Down
9 changes: 3 additions & 6 deletions znet/bind_router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"testing"

"github.com/sohaha/zlsgo"
"github.com/sohaha/zlsgo/zdi"
"github.com/sohaha/zlsgo/ztype"
)

Expand All @@ -22,16 +21,14 @@ type testController struct{}

func (t *testController) Init(e *Engine) {
e.Log.Debug("initialization")
}

func (t *testController) PreInvoker() []zdi.PreInvoker {
return []zdi.PreInvoker{(*invokerCodeText)(nil)}
RegisterPreInvoker((invokerCodeText)(nil), (*CustomInvoker)(nil))
}

func (t *testController) GETUser(_ *Context) {
}

func (t *testController) GETGetUser(_ *Context) {
func (t *testController) GETGetUser(_ *Context) (b []byte) {
return []byte("GETUser")
}

func (t *testController) POSTUserInfo(_ *Context) {
Expand Down
32 changes: 22 additions & 10 deletions znet/inject.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,21 +143,33 @@ func (utils) ParseHandlerFunc(h Handler) (fn handlerFn) {
}
default:
val := zreflect.ValueOf(v)
if val.Kind() != reflect.Func {
b := ztype.ToBytes(v)
isJSON := zjson.ValidBytes(b)
return func(c *Context) error {
c.Byte(http.StatusOK, b)
if isJSON {
c.SetContentType(ContentTypeJSON)

var fn interface{}
for i := range preInvokers {
if val.Type().ConvertibleTo(preInvokers[i]) {
fn = val.Convert(preInvokers[i]).Interface()
break
}
}

if fn == nil {
if val.Kind() != reflect.Func {
b := ztype.ToBytes(v)
isJSON := zjson.ValidBytes(b)
return func(c *Context) error {
c.Byte(http.StatusOK, b)
if isJSON {
c.SetContentType(ContentTypeJSON)
}
return nil
}
return nil
// panic("znet Handler is not a function: " + val.Kind().String())
}
// panic("znet Handler is not a function: " + val.Kind().String())
fn = v
}

return func(c *Context) error {
v, err := c.injector.Invoke(v)
v, err := c.injector.Invoke(fn)

if c.stopHandle.Load() {
return nil
Expand Down

0 comments on commit 76c1152

Please sign in to comment.