-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flexible Handle Type #39
Comments
I think matching the method signature with the standard http.Handler interface would be ideal. Possibly when there are parameters you could do something similar to other packages and use the querystring with keys like ":querystringkey" ? |
+1 for matching http.Handler |
We implemented this on top of httprouter here: https://github.com/nbio/hitch It uses per-request contexts from: https://github.com/nbio/httpcontext |
I like it the way it is. With closures, it's already plenty flexible enough IMHO. |
Another thought: if httprouter mirrored the http package and used a Handler type type Handler interface { and the underlying storage was changed to store Handler rather than Interface types can be nicer to debug too, being less opaque |
I'd love this implemented too. |
It is possible to wrap request body as interface. See the example: package vanilla
// based on https://github.com/nbio/httpcontext
// authored by http://nb.io https://github.com/nbio.
// MIT License
import (
"io"
"net/http"
)
// Param is a single URL parameter, consisting of a key and a value.
type Param struct {
Key string
Value string
}
// Params is a Param-slice, as returned by the router.
// The slice is ordered, the first URL parameter is also the first slice value.
// It is therefore safe to read values by the index.
type Params []Param
// ByName returns the value of the first Param which key matches the given name.
// If no matching Param is found, an empty string is returned.
func (ps Params) ByName(name string) string {
for i := range ps {
if ps[i].Key == name {
return ps[i].Value
}
}
return ""
}
// Parameters returns all path parameters for given
// request.
//
// If there were no parameters and route is static
// then nil is returned.
func Parameters(req *http.Request) Params {
return parameterized(req).get()
}
type paramReadCloser interface {
io.ReadCloser
get() Params
set(Params)
}
type parameters struct {
io.ReadCloser
all Params
}
func (p *parameters) get() Params {
return p.all
}
func (p *parameters) set(params Params) {
p.all = params
}
func parameterized(req *http.Request) paramReadCloser {
p, ok := req.Body.(paramReadCloser)
if !ok {
p = ¶meters{ReadCloser: req.Body}
req.Body = p
}
return p
} And usage example would be: router.GET("/all/*node", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "got var: "+Parameters(req).ByName("node"))
})) |
@tj guess you should be very excited to see this https://github.com/DATA-DOG/fastroute have a look at Router interface maybe it is not the right place to add such a link, but well, worth it.. |
What do you think about making the
Lookup
method (or a similar one) more generic in terms of not enforcing a specific function footprint?Currently, when building something on top of
httprouter
, each handler has to be afunc(w http.ResponseWriter, r *http.Request, _ httprouter.Params)
. It would be nice if theLookup
method (or a similar one) returns aninterface{}
, whilehttprouter
itself still enforces thehttprouter.Handle
type for its own public API. This would allow using custom handle types for modules build on top ofhttprouter
.The text was updated successfully, but these errors were encountered: