Weekly Review — Month 4 · Week 1 (Days 085–091)¶
📅 The Week in One Line¶
Building real HTTP services with the standard library: the http.Handler
interface, Go 1.22 routing, composable middleware, JSON helpers, and a graceful
server lifecycle.
✅ What I Completed¶
- Day 085 —
http.Server+ Go 1.22ServeMux: methods,{id}/{path...}/{$}, auto 404/405 - Day 086 —
http.Handlerinterface & theHandlerFuncadapter - Day 087 — Routing with chi: sub-routers, regex params, route groups (snippet-only, third-party)
- Day 088 — Middleware chains:
func(http.Handler) http.Handler,Chain, RequestID/Logger/Recoverer - Day 089 — JSON request/response helpers: strict bounded decoding, uniform errors
- Day 090 — Graceful shutdown & timeouts:
Server.Shutdown,ErrServerClosed,signal.NotifyContext - Day 091 — Review + closed-book recall
- Mini-project: a stdlib-only widgets API (servemux + middleware + JSON + graceful shutdown)
- Exercises solved: 3 (respond, middleware, pathrouter) — all green,
-race-clean
💡 Lessons Learned¶
- The entire
net/httpecosystem is one interface (ServeHTTP); everything else is wrappers and adapters around it. - Go 1.22's mux removed most reasons to reach for a router on small services — method routing, path wildcards, and automatic 405 are built in.
- Middleware order is the whole game:
Chain(A, B, C)makesAoutermost, and Recoverer must sit near the top to catch inner panics (same-goroutine only). - Robust JSON decoding is mostly defensive flags:
MaxBytesReader,DisallowUnknownFields, adec.More()check, and mapping errors to 4xx codes. http.ErrServerClosedis a success signal — treating it as fatal was the classic graceful-shutdown bug.
💪 Strengths (what clicked)¶
- Reading path wildcards with
r.PathValueinstead of slicing URLs. - The
func(http.Handler) http.Handlermiddleware shape and composing it. - Header-before-
WriteHeaderordering and why the status freezes.
🧩 Weaknesses (what's still fuzzy)¶
- Forwarding optional
ResponseWriterinterfaces (Flusher/Hijacker) through a wrapping middleware. - chi's
NotFound/MethodNotAllowedcustomisation vs. the stdlib defaults. - Choosing sane timeout values for a given workload (needs real traffic shapes).
🔁 Spaced-Repetition Re-quiz (topics from earlier weeks)¶
- Q: (M1) What does
string(65)produce and why?A
"A"— int→rune to code point U+0041, not"65". Usestrconv.Itoa. - Q: (M2) What does
%winfmt.Errorfdo?A
Wraps an error soerrors.Is/errors.Ascan unwrap and match it. - Q: (M3) Sending on a closed channel vs a nil channel?
A
Closed → panic; nil → blocks forever. - Q: (M3) Why must
context.Contextbe the first parameter?A
Convention for cancellation/deadline propagation; tooling and readers expectctxfirst. - Q: (M4) Why use an unexported type for context keys?
A
So your key can't collide with a key created in another package — value keys are compared by type and value.
🎯 Action Items¶
- Add a status-capturing
ResponseWriterwrapper that also forwardshttp.Flusherand test streaming. - Benchmark stdlib mux vs chi on a nested route tree to quantify the tradeoff.
- Wire the Week 1 widgets API to a real datastore once Week 2 covers
database/sql.
🚀 Next Week Goals¶
database/sql:DB,Conn,Stmt,Rows,QueryContext/ExecContext, connection pooling,contextdeadlines on queries.- Drivers (pgx) and code-gen (sqlc) at the concept level; repository pattern, migrations, and transactions modelled with the stdlib.
- Pull the HTTP layer and the data layer together into a small REST service.
📊 Metrics¶
| Hours | Days hit | Exercises | Commits | Avg confidence |
|---|---|---|---|---|
| 9 | 7/7 | 3 | 7 | 3.⅗ |
Suggested commit: docs(journal): month 4 week 1 review