Function as argument, access inner parameter

855 Views Asked by At

The package valyala/fasthttp implements the following function type:

type RequestHandler func(ctx *RequestCtx)

It is used in buaazp/fasthttprouter like this:

func (r *Router) Handle(method, path string, handle fasthttp.RequestHandler) {
    //...
}

I am trying to wrap these like this (open for suggestions on implementation):

//myapp/router

type Request struct {
    fasthttp.RequestCtx
}

type RequestHandler func(*Request)

func Handle(method string, path string, handler RequestHandler) {
    //I need to access the fasthttp.RequestCtx stuff in here...
}

How can I achieve this? Or, if this is not the way to go at all, how can I achieve my goal as mentioned below for a router package?


BACKGROUND

Goal: My wish is to wrap tooling packages (sessions, database, routing, etc.) in order to make my app agnostic to the implementation of these packages. I wish to do this primarily for the purpose of being able to extend these with domain-specific functionality, and being able to switch one 3rd party lib for another, if I ever would need to do so. It also makes debugging and logging easier.

Method: I create native types and functions, which map to the functionality of the imported packages.

Problem: I am stuck on how to wrap a foreign (i.e. imported) function type properly.

1

There are 1 best solutions below

5
On

At all your idea looks very good. Some things you could change:

//myapp/router    

// Using a composition is idiomatic go code 
// this should work. It can't get better.
type Request struct {
    fasthttp.RequestCtx
}

// I would make the RequestHandler as a real Handler. In go it would be
// a interface
type RequestHandler interface{
   Request(*Request)
}
// If you have a function, which needs to access parameters from `Request`
// you should take this as an input.
func Handle(method string, path string, req *Request) {
    //Access Request via req.Request ...
}

Because if you pass a function or an interface into your function, which needs also Request as input the caller needs to create that before he calls your Handle function. Why not change that function just for the input you really need?