http.Handler
- Go course
- Intermediate
- Lesson 67/80
- 4 min
Learn the Handler interface and ServeHTTP.
http.Handler
At the heart of the server side is a single-method interface:
type Handler interface {
ServeHTTP(w http.ResponseWriter, r *http.Request)
}r carries everything about the request (method, path, headers, body, context); w writes the status code, headers and body. Any type with a ServeHTTP method is a handler, so handlers that hold state can be written as structs.
A stateful handler
A struct handler that takes its dependencies (database, logger, settings) helps avoid global variables:
type SayacHandler struct {
mu sync.Mutex
n int
}
func (h *SayacHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.mu.Lock()
h.n++
n := h.n
h.mu.Unlock()
fmt.Fprintf(w, "ziyaret: %d", n)
}Because the server handles every request in its own goroutine, shared state is protected by a lock.
Practice Struct handler
Write the SayacHandler above. Send two requests to the same handler with httptest.NewRecorder and print the body of the second response.
Starter code
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"sync"
)
func main() {
// buraya yaz
}Sample solution
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"sync"
)
type SayacHandler struct {
mu sync.Mutex
n int
}
func (h *SayacHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.mu.Lock()
h.n++
n := h.n
h.mu.Unlock()
fmt.Fprintf(w, "ziyaret: %d", n)
}
func main() {
h := &SayacHandler{}
h.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil))
rec := httptest.NewRecorder()
h.ServeHTTP(rec, httptest.NewRequest("GET", "/", nil))
fmt.Println(rec.Body.String())
}Expected output
ziyaret: 2
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What is the correct order for setting a response header?
- Header().Set → WriteHeader → Write Correct answer
- Write → Header().Set
- WriteHeader → Header().Set → Write
- The order doesn't matter
Explanation: WriteHeader (or the first Write) sends the headers; Header().Set changes made after that have no effect.
2 Interface method
func (h *Api) ____(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
}
func (h *Api) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
}
Explanation: Any type with a ServeHTTP method satisfies the http.Handler interface.
3 Request field
| Term | Meaning |
|---|---|
r.Method |
GET, POST... |
r.URL.Path |
Path |
r.Header |
Headers |
r.Context() |
Cancellation and values |