preslavrachev / preslav.me-comments

0 stars 0 forks source link

2022/08/09/i-dont-like-golang-default-http-handlers/ #11

Open utterances-bot opened 1 year ago

utterances-bot commented 1 year ago

I Don’t Like Go’s Default HTTP Handlers · Preslav Rachev

I am a software engineer with a decade-long experience developing software using Go, Python, and Elixir.

https://preslav.me/2022/08/09/i-dont-like-golang-default-http-handlers/

nfisher commented 1 year ago

The return error works well when all client calls are serial but you run into a similar issue when calls are made in parallel using go routines. The implication for me is that adequate testing needs be employed using either a check on the handler or a full end-to-end test.

quinqu commented 1 year ago

I've always thought the same thing! Great post.

Another approach to help prevent naked returns is writing a script that takes a .go file as input and tells you where you may have forgotten a return -- like gofmt -d but where you don't return after http.Error.

preslavrachev commented 1 year ago

I've always thought the same thing! Great post.

Another approach to help prevent naked returns is writing a script that takes a .go file as input and tells you where you may have forgotten a return -- like gofmt -d but where you don't return after http.Error.

@quinqu This is actually possible using one of the popular Go linters out there. golangci-lint has one such check, as well as go-critic. I realize now that I should probably write an update to my original post and list those options too.

nicolasparada commented 1 year ago

This small library can help on that https://github.com/caarlos0/httperr

nahwinrajan commented 1 year ago

I don't think the proposed bug can happen. My understanding through the documentation is that the connection will be close after you write to the response.Wrinter -> The Response Body is closed after it is sent.

You may still use resources in your machine due to not returning though..

nfisher commented 1 year ago

@nahwinrajan the underlying problem is that there's a host of behaviour that might happen after the error block but shouldn't. In the best case as you say it's additional latency/resource consumption, in the worst-case it's non-deterministic behaviour that could result in something undesired.

grz-gajda commented 1 year ago

I still don't like writing directly to the http.ResponseWriter. That's why I copied idea from Symfony framework and its HTTP component where each handler need to return an instance of Response object: devmint/go-restful. It's simple wrapper for chi framework where you always need to return a Response struct.

    router.Post("/", func(r request.Request) response.Response {
        return response.Ok("welcome")
    })

    router.Post("/", func(r request.Request) response.Response {
        body := customBody{}
        if err := r.Body(&body); err != nil {
            return response.BadRequest(err)
        }

        return response.Ok(body.A)
    })
nahwinrajan commented 1 year ago

@nfisher yeah but that is not problem / bug of standard HTTP handler right?