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?
returnyou 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.http.ResponseWriteris implemented by a pointer type. This allows any copy of thewinstance to invoke the methods on the same receiver and modify the same data living at the same memory address.http.ResponseWriterwere 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.