Challenge 2 - Microservice
- Go course
- Advanced
- Lesson 66/68
- 8 min
Write a service with HTTP API + database + Docker.
Challenge: a robust service
You will combine three pieces that make an HTTP service production-ready: middleware that adds a request ID, recover middleware that turns panics into 500, and a mux serving only the GET /urunler/{id} route. An unknown id returns 404.
chain: recoverMW → istekID → mux
GET /urunler/1 → 200 "Kalem"
GET /urunler/9 → 404Plan
1) urunler := map[string]string{"1": "Kalem"}. 2) Look up with r.PathValue("id") inside mux.HandleFunc("GET /urunler/{id}", ...). 3) h := recoverMW(istekID(mux)). 4) Send two requests with httptest and print the codes. Write the middleware as in earlier groups; order matters: recover outermost.
Practice Build the service
Implement the plan above. Print the status codes of GET /urunler/1 and GET /urunler/9 on one line.
Starter code
package main
import (
"fmt"
"net/http"
"net/http/httptest"
)
func main() {
// buraya yaz
}Sample solution
package main
import (
"fmt"
"net/http"
"net/http/httptest"
)
func recoverMW(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if v := recover(); v != nil {
http.Error(w, "sunucu hatası", 500)
}
}()
next.ServeHTTP(w, r)
})
}
func istekID(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Request-ID", "r1")
next.ServeHTTP(w, r)
})
}
func main() {
urunler := map[string]string{"1": "Kalem"}
mux := http.NewServeMux()
mux.HandleFunc("GET /urunler/{id}", func(w http.ResponseWriter, r *http.Request) {
ad, ok := urunler[r.PathValue("id")]
if !ok {
http.NotFound(w, r)
return
}
fmt.Fprint(w, ad)
})
h := recoverMW(istekID(mux))
kod := func(yol string) int {
rec := httptest.NewRecorder()
h.ServeHTTP(rec, httptest.NewRequest("GET", yol, nil))
return rec.Code
}
fmt.Println(kod("/urunler/1"), kod("/urunler/9"))
}Expected output
200 404
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 If you read the route id and don't find it in the map, what do you do?
- Return 200 with an empty body
- Shut the server down
- Return 404 with http.NotFound(w, r) Correct answer
- Call panic
Explanation: A missing resource is an expected case; it is reported with 404, not a panic.
2 Path variable
ad, ok := urunler[r.____("id")]
ad, ok := urunler[r.PathValue("id")]
Explanation: PathValue reads the {id} variable from the route pattern.
3 Piece and role
| Term | Meaning |
|---|---|
recoverMW |
Panic → 500 |
istekID |
X-Request-ID |
mux |
Routing |
http.NotFound |
404 response |