diff --git a/handler.go b/handler.go index b6feeb3..662daf3 100644 --- a/handler.go +++ b/handler.go @@ -51,7 +51,8 @@ func (s Handler) handleRequest(w http.ResponseWriter, r *http.Request) { } // 5. pass execution to the handler - var outData, outErr = handler.dyn.Handle(input.Data) + ctx := api.Ctx{Res: w, Req: r} + var outData, outErr = handler.dyn.Handle(ctx, input.Data) // 6. build res from returned data var res = api.EmptyResponse().WithError(outErr) diff --git a/internal/dynfunc/handler.go b/internal/dynfunc/handler.go index f7566c8..f47eed9 100644 --- a/internal/dynfunc/handler.go +++ b/internal/dynfunc/handler.go @@ -15,6 +15,8 @@ type Handler struct { fn interface{} // whether fn uses api.Ctx as 1st argument hasContext bool + // index in input arguments where the data struct must be + dataIndex int } // Build a handler from a service configuration and a dynamic function @@ -39,13 +41,11 @@ func Build(fn interface{}, service config.Service) (*Handler, error) { } h.hasContext = impl.NumIn() >= 1 && reflect.TypeOf(api.Ctx{}).AssignableTo(impl.In(0)) - - inputIndex := 0 if h.hasContext { - inputIndex = 1 + h.dataIndex = 1 } - if err := h.spec.checkInput(impl, inputIndex); err != nil { + if err := h.spec.checkInput(impl, h.dataIndex); err != nil { return nil, fmt.Errorf("input: %w", err) } if err := h.spec.checkOutput(impl); err != nil { @@ -56,14 +56,19 @@ func Build(fn interface{}, service config.Service) (*Handler, error) { } // Handle binds input @data into the dynamic function and returns map output -func (h *Handler) Handle(data map[string]interface{}) (map[string]interface{}, api.Err) { +func (h *Handler) Handle(ctx api.Ctx, data map[string]interface{}) (map[string]interface{}, api.Err) { var ert = reflect.TypeOf(api.Err{}) var fnv = reflect.ValueOf(h.fn) callArgs := []reflect.Value{} + // bind context if used in handler + if h.hasContext { + callArgs = append(callArgs, reflect.ValueOf(ctx)) + } + // bind input data - if fnv.Type().NumIn() > 0 { + if fnv.Type().NumIn() > h.dataIndex { // create zero value struct callStructPtr := reflect.New(fnv.Type().In(0)) callStruct := callStructPtr.Elem()