3

I can't understand a part of the ResponseWriter syntax.

type ResponseWriter interface {
    Header() Header
    Write([]byte) (int, error)
    WriteHeader(statusCode int)
}

For instance, in the example provided in go by example, the area method was implemented by both objects implementing geometry interface.

The http.ResponseWriter is an interface, which is capable of Write, amongst other things.

I've written the following to test the value of w ResponseWriter

func sendData(w http.ResponseWriter, r *http.Request) {
    fmt.Println(w)
}

func main() {
    http.HandleFunc("/", sendData)
    http.ListenAndServe(":8081", nil)
}

The returned result in a browser was blank

In the terminal where the code was executed, I obtained the following stdout:

&{0xc00009ebe0 0xc0000e8100 {} 0x112a550 false false false false 0xc00006c500 {0xc0000d40e0 map[] false false} map[] false 0 -1 0 false false [] 0 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0] 0xc0000200e0 0}

Being an interface, it relies on the underlying type to do the actual writing but what is the underlying type and where is the write implemented?

Christian
  • 1,676
  • 13
  • 19
Coder
  • 51
  • 4
  • 1
    Two very good tips: 1) Redo the Tour of Go for all the language fundamentals. 2) Always and I really mean always read the documentation of all functions and packages you use, here fmt.Println. Unless documentation you might be used to the Go documentation is short, helpful an necessary. – Volker Mar 24 '21 at 09:59

1 Answers1

9

fmt.Println(w) does not write into w. It writes w to the standard output. And since nobody writes into w, an empty response document will be sent back to the HTTP client.

To write into w, call its Write() method like this:

w.Write([]byte("hello"))

Then you'll see the hello response document.

Note that there is an fmt.Fprintln() variant to which you can tell where to write to. So you may pass w as the destination for writing:

fmt.Fprintln(w, "hello")

Then you'll see a hello response document.

To get the concrete type that implements http.ResponseWriter, print the type like this:

fmt.Printf("%T\n", w)

Then you'll see an output like this:

*http.response

So the type that is passed to you and implements http.ResponseWriter is the unexported type http.response (more specifically a pointer to it). It's unexported so you can't "touch" it, but for educational purposes, it's defined in net/http/server.go, currently at line #418.

For more options and deeper insight, see related question: What's the difference between ResponseWriter.Write and io.WriteString?

icza
  • 389,944
  • 63
  • 907
  • 827
  • 5
    Wow, thanks! your response really enlightened me and helped me to understand more about Go. – Coder Mar 24 '21 at 09:59