Table of Contents
- Month 4 — Runnable Examples
- How to run
- Index (Week 1 — net/http, routing, middleware, JSON, lifecycle)
- Index (Week 2 — databases, pooling, migrations, repositories, transactions)
- Index (Week 3 — validation, logging, config, rate limiting, auth)
- Index (Week 4 — capstone: layered architecture, integration tests, OpenAPI)
Month 4 — Runnable Examples¶
Single-concept, stdlib-only programs backing the Month 4 daily notes
(web, REST APIs & databases). Each folder is its own package main.
How to run¶
Index (Week 1 — net/http, routing, middleware, JSON, lifecycle)¶
| Topic | Concept | Day |
|---|---|---|
servemux/ |
http.Server + Go 1.22 method/pattern routing, {id}, {path...}, {$}, auto-405 |
085 |
middleware/ |
func(http.Handler) http.Handler, a Chain combinator, request-id / logger / recoverer |
088 |
json-api/ |
writeJSON/decodeJSON helpers, DisallowUnknownFields, MaxBytesReader, struct tags |
089 |
graceful/ |
server timeouts, signal.NotifyContext, Server.Shutdown, ErrServerClosed |
090 |
chi routing (Day 087) needs
github.com/go-chi/chi/v5, a third-party module outside the stdlib, so it lives as a snippet in the day note rather than as a runnable example here. Theservemux/example shows how far the standard library alone now gets you.Tip: the JSON and routing handlers are unit-tested with
net/http/httptestinexercises/month-04/week-1/— no live server needed.
Index (Week 2 — databases, pooling, migrations, repositories, transactions)¶
| Topic | Concept | Day |
|---|---|---|
pool/ |
bounded connection pool from a buffered channel; Acquire(ctx) respects cancellation; defer Release |
093 |
migrate/ |
forward-only, idempotent migration runner ordered by integer version; duplicate-version guard | 095 |
repository/ |
repository pattern: consumer-side interface + in-memory adapter; domain ErrNotFound/ErrConflict via errors.Is |
096 |
txn/ |
Begin → Commit/Rollback over an in-memory store; the deferred-Rollback WithTx helper; context-checked commit |
097 |
database/sql (Day 092), pgx / pgxpool (Day 093) and sqlc (Day 094) all require a real driver or a third-party module (
github.com/jackc/pgx/v5, thesqlcgenerator), so they live as snippets in the day notes. The examples above model the underlying concepts — pooling, migrations, repositories, transactions — with the standard library only, so they compile and run here.Tip: the planner, repository and transaction logic are unit-tested in
exercises/month-04/week-2/— no live database needed.
Index (Week 3 — validation, logging, config, rate limiting, auth)¶
| Topic | Concept | Day |
|---|---|---|
validation/ |
decode-then-validate, FieldErrors collected, 400 vs 422, net/mail.ParseAddress |
099 |
reqlog/ |
per-request log/slog line; ResponseWriter wrapper for status/bytes; request-id in context |
100 |
ratelimit/ |
per-client token bucket (rate vs burst), lazy refill under a mutex, 429 + Retry-After, idle eviction |
103 |
jwt/ |
stdlib HS256 sign/verify, alg-pinning, hmac.Equal, exp, RequireRole RBAC middleware (401 vs 403) |
104 |
pagination (Day 101) and env config (Day 102) are pure logic, so they live as tested packages in
exercises/month-04/week-3/(paginate,envconfig) rather than as runnable servers.golang.org/x/time/rate(Day 103) andgithub.com/golang-jwt/jwt(Day 104) are third-party, so theratelimit/andjwt/examples model the same algorithms with the standard library only — production should reach for those packages.
Index (Week 4 — capstone: layered architecture, integration tests, OpenAPI)¶
| Topic | Concept | Day |
|---|---|---|
layered/ |
full handler → service → repo wiring; domain errors mapped to HTTP status in one place; in-process httptest.Server demo |
106 |
httptest/ |
integration testing with httptest.NewRecorder vs httptest.NewServer; MaxBytesReader + DisallowUnknownFields |
109 |
openapi/ |
model an OpenAPI 3.0 document as structs, marshal to JSON, serve /openapi.json + a docs page |
110 |
testcontainers (Day 109) (
github.com/testcontainers/testcontainers-go), swaggo/swag (Day 110), the Dockerfile/CI tooling (Day 111), and the chi/pgx stack the real project uses are third-party or out-of-band, so they live as snippets in the day notes. Thehttptest/example models the exact "boot the app, hit it like a client, assert" loop that a containerised test performs — only the database backing it differs.Tip: the service, handler and OpenAPI builder are unit-tested in
exercises/month-04/week-4/—go test ./exercises/month-04/week-4/....