Nice package. I like the fact that it's limited in scope and actually does some work for you. There's a trick you're missing though - you require the user to pass in their expected params struct explicitly so you can reflect on its type, but you could just reflect on the handler function type itself.
Then a handler function could look like this:
func Do(w http.ResponseWriter, r *http.Request, params *DoParams) {
w.Write([]byte(params.Var))
}
No need for any dynamic type coercion - it can all be checked up front when the handlers are registered. The down side is that the signature of Handle would become more opaque (its argument would just be an interface{}) and you'd probably want to lose the Handler type.
FWIW, passing an empty struct for the sole purpose of being inspected using reflection is not unusual (see for example gob.Register).
I'm aware of this, however there is a pretty serious downside: function decorators (currying, whatever you want to call it) become difficult if type information is encoded in the function signature. For example, I mark handlers for logged in users by:
handle(..., User(F))
The prototype of F and User might be
func F(w http.ResponseWriter, r *http.Request, s *Session, i interface{})
func User(...type of F...) func (http.ResponeWriter, r *http.Request, i interface{})
User() would do some preprocessing on the request and produce a Session for F. The problem is that User accepts ...type of F...; although it could accept an interface (of a function) but doing everything by reflection becomes cumbersome.
This is one of the things I don't like about go but really you need a type system like haskell's to achieve what I want here.
Then a handler function could look like this:
No need for any dynamic type coercion - it can all be checked up front when the handlers are registered. The down side is that the signature of Handle would become more opaque (its argument would just be an interface{}) and you'd probably want to lose the Handler type.FWIW, passing an empty struct for the sole purpose of being inspected using reflection is not unusual (see for example gob.Register).