0

I am learning Go and have a quick question about http handler implementation in Go. I am asking it in a small sample code.

So assume there is a handler function called Test() as defined like below

      func Test() func(http.ResponseWriter, *http.Request) {
        return func(w http.ResponseWriter, r *http.Request) {
            params := r.URL.Query()
            name := params.Get("name")
            if name == "axy" {
                common.UpdateHttpResponse("Trying to updating the response", w, http.StatusBadRequest)
                //return
            }
            w.WriteHeader(http.StatusOK)
        }
    }

lets say the UpdateHttpResponse method is also define in common package as below:

func LogExtractionErrorResponse(errMsg string, w http.ResponseWriter, responseHeader int) {
    fmt.Printf("%s", errMsg)
    jsonErrorOut := map[string]string{
        "Error": errMsg,
    }
    w.WriteHeader(responseHeader)
    encodedResponse, _ := json.Marshal(jsonErrorOut)
    if w != nil {   
        w.Write(encodedResponse)
    }
}

I call the Test() HTTP handler in the http server part as below.

// this is how Test() http handler is called as well
          http.HandleFunc("/test", httpserver.Test())

So here is my question:

  • Based on my understanding all values are passed by value in go (as discussed in this thread as well)
  • In that case why if the http handler is called with a parameter (i.e localhost:PORT_NUM/test?name=axy), i observe "StatusBadRequest" in resonse. In other words, why the commented "return" keyword is not needed and why the header response is not overwritten by "w.WriteHeader(http.StatusOK)" at the end of Test() http handler?
Ashkanxy
  • 2,380
  • 2
  • 6
  • 17
  • 2
    While you do not need the `return` you should keep it, writing header twice is not an error but is just poor practice. The second write doesn't overwrite the first because HTTP requires the status code to be on top, after that you write the rest of the headers and after that the body, allowing overwriting would disallow steaming. I'll take streaming over overwriting any day. – mkopriva Oct 05 '21 at 17:38
  • 1
    A copy of a pointer will still point to the same address as the original. The interface `http.ResponseWriter` is implemented by a pointer type. This allows any copy of the `w` instance to invoke the methods on the same receiver and modify the same data living at the same memory address. – mkopriva Oct 05 '21 at 17:47
  • 3
    Even if the default `http.ResponseWriter` were implemented by a value type, it could have pointers stored within it, or it could call out to other methods defined with pointer receivers. What this essentially means is that the methods work the way they are documented, and nothing more. – JimB Oct 05 '21 at 17:51
  • https://play.golang.org/p/gpBowPwM4go – mkopriva Oct 05 '21 at 18:08

0 Answers0