Live data from Hacker News

The problem with Go’s default HTTP handlers

preslav.me

11–20 of 97 posts

Re: The problem with Go’s default HTTP handlers

#15
post #5
post #3

It's not something I even thought about, but I guess I see the point, I just don't agree. In the HTTP handlers it makes sense that you don't have return values, because: What would you do with that value exactly? The HTTP handler should always ensure that "something" is returned, at the very least a return code. Once something has been returned to the client, can you really argue that there's an error? There's a poin…

"In the HTTP handlers it makes sense that you don't have return values, because: What would you do with that value exactly?" I agree that the baseline net/http implementation is correct. There is no appropriate default error (return) handler that the framework could implement, at the level it lives at, that would be correct and wouldn't be limiting. However I very often in my own Go code immediately create an abstrac…

"net/http" doesn't seem to come with a lot of great defaults that almost every web app would use such as named path parameters which you'd need to write a bunch of code and regex to extract, middleware, routing based on HTTP method etc. This is all stuff you'd have to implement anyway

I'd much prefer using something that's an abstraction of it like Gin, Chi, Echo and the like. They're fairly performative and add very little overhead on top of the standard package

Re: The problem with Go’s default HTTP handlers

#16
post #9

Another possible extension of that design is using error types for HTTP codes. Something like: type HTTPError struct { Err error Code int } And then, with a couple of wrappers like this: func errorNotFound(err error) (wrapped error) { return &HTTPError{ Err: err, Code: http.StatusNotFound, } } you could do something like this: return errorNotFound(err) or this: return errorInternal(err) // 500 Internal Server Error

I usually create an abstraction like this in an API to require all returned errors to come with some sort of machine readable code. You either have to classify this response with an existing code in the list or add a new one. That list then gets generated as part of the documentation so consumers are getting possible error states straight from the code (without having to look at said code).

Re: The problem with Go’s default HTTP handlers

#18
I dont necessarily agree they should return a value, but I do have some issues with the api:

- by default, you can't tell if a handler has already written to the body or emitted a status code.

- by default, you can't read the body more than once

- r.PostForm vs r.Form ...that they both exist, and that they're only available after a manual call to r.ParseForm

- the http server accepts an unbounded number of connections. it'll just keep making goroutines as they come in. there's no way that I know of to apply back pressure.

there's probably more that I grump about, but those are the ones at the top of my mind. for the most part it works well, and i can work around my gripes.

Re: The problem with Go’s default HTTP handlers

#19
post #4

I like the way Axum for Rust handles this. All response handlers return something that implements IntoResponse. Lots of types implement IntoResponse, thus making the simple cases really streamlined. async fn create_user( Json(payload): Json , ) -> impl IntoResponse { let user = User { id: 1337, username: payload.username, }; // this will be converted into a JSON response // with a status code of `201 Created` (Status…

That is what Gin does.
Post reply on HN