Skip to content
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

Nasty lack of compilation errors for http.Handler, http.HandlerFunc #29354

Closed
ORESoftware opened this issue Dec 20, 2018 · 1 comment
Closed

Comments

@ORESoftware
Copy link

ORESoftware commented Dec 20, 2018

What version of Go are you using (go version)?

go version go1.10.4 linux/amd64

Problem

http.Handler / http.HandlerFunc types need be differentiated - things are compiling which shouldn't compile.

Say we have this func:

func AuthMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		next.ServeHTTP(w, r)
	})
}

the above will compile. But so will this:

func AuthMiddleware(next http.Handler) http.HandlerFunc {   // >>> HandlerFunc instead of Handler
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		next.ServeHTTP(w, r)
	})
}

and so will this:

func AuthMiddleware(next http.Handler) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {  // >>> did not wrap with http.HandlerFunc
		next.ServeHTTP(w, r)
	}
}

the problem is at runtime these 3 behave very differently, my question is - do people see this as a problem and can it be rectified. I am getting all sorts of runtime errors by accidentally mixing these 3 things and it's driving me a little insane.

@jimmyfrasche
Copy link
Member

Values of http.HandlerFunc satisfy the http.Handler interface, which is why the first example works.

The underlying type of http.HandlerFunc is func(w http.ResponseWriter, r *http.Request). This is why examples 2 and 3 are equivalent.

You can write these examples with just variable assignment, which makes what's happening a bit clearer: https://play.golang.org/p/lGypXvNemVK

As for http.HandlerFunc and http.Handler behaving differently, the very short definition of HandlerFunc may enlighten: https://golang.org/src/net/http/server.go?s=59707:59754#L1950

It can be a bit confusing at first since there's quite a few concepts in the language at play simultaneously, but this is all working as intended, so I'm closing.

If you have thoughts about how the package should change in the future, #5465 is where that discussion is taking place.

@golang golang locked and limited conversation to collaborators Dec 20, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants