Monthly Review — Month 4: Web, REST APIs & Databases¶
🎬 Headline¶
I can design, build, test, document, and ship a production-shaped REST service in Go — layered architecture over a real database, with integration tests, an OpenAPI contract, and a CI-built container.
🛠️ Skills Acquired¶
| Skill | Confidence (1-5) | Evidence (link) |
|---|---|---|
net/http servers + Go 1.22 routing |
4 | examples/month-04/servemux |
| Middleware chains (logging, recovery, auth, rate limit) | 4 | examples/month-04/middleware |
| JSON request/response handling + validation | 4 | examples/month-04/validation |
database/sql: pooling, migrations, repositories, transactions |
3 | examples/month-04/repository · txn |
| Layered architecture + dependency inversion | 4 | examples/month-04/layered |
Integration testing (httptest + testcontainers) |
3 | examples/month-04/httptest |
| OpenAPI documentation | 3 | examples/month-04/openapi |
| Multi-stage Docker + GitHub Actions CI | 3 | Day 111 snippets |
📦 Projects Completed¶
- Layered REST service (Users/Notes API) — project repo · key learning: dependencies point inward through consumer-owned interfaces, so every layer is independently testable and the database/transport is swappable.
💡 Lessons Learned¶
- "Accept interfaces, return structs" is the load-bearing idiom: define the
Repointerface next to the service, not the database. - Errors should be translated at exactly two boundaries: driver→domain (repository) and domain→HTTP status (handler).
context.Contextthreaded first-parameter from handler to query makes the whole request cancellable.- Fast unit tests (fakes) and high-fidelity integration tests (real DB) are complementary, not either/or — gate the slow ones behind a build tag.
- Small, immutable, non-root container images are mostly a Dockerfile-structure problem (multi-stage + static binary + distroless).
📉 Areas for Improvement¶
- pgx-native API depth (batching,
COPY, listen/notify) beyond thedatabase/sqllayer. - CI supply-chain hardening:
govulncheck, SBOMs, image signing. - Documenting auth and error envelopes consistently in OpenAPI.
🔁 Concepts to Keep Reviewing (carry into spaced repetition)¶
- 400 vs 422 vs 409 status selection.
defer rows.Close()+rows.Err()discipline to avoid connection leaks.- Constant-time signature comparison (
hmac.Equal) for auth. - Forward-only, versioned migrations — never edit an applied one.
- nil-interface trap when returning a typed-nil error/pointer from a layer.
🧑💼 Interview Readiness¶
| Area | Ready? | Notes |
|---|---|---|
| Language fundamentals | ✅ | solid from Months 1–2 |
| Concurrency | 🟨 | comfortable; revisit errgroup/pipelines under load |
| Web/DB | ✅ | can whiteboard layered REST + DB design and justify trade-offs |
🎒 Portfolio Updates¶
- Updated project README + architecture diagram and
curlexamples - New résumé bullet: "Built a layered REST API in Go (net/http, database/sql, OpenAPI) with httptest + testcontainers integration tests, shipped as a ~15 MB distroless container via CI."
- Pinned/featured: the Month 4 capstone repository
- Tagged release
v0.4.0+ wrote release notes
📊 Metrics¶
| Total hours | Days completed | Exercises | Projects | Books/articles | Avg confidence |
|---|---|---|---|---|---|
| 42 | 28/28 | 11 | 1 | 9 | 3.5/5 |
⏭️ Next Month Preview¶
Month 5 moves beyond a single service: gRPC and inter-service communication, message queues/async work, and observability (metrics, traces, structured logs). I'll prepare by re-reading the concurrency notes and standing up the new project skeleton with the same layered discipline.
Suggested commit: docs(journal): month 4 review then git tag -a v0.4.0 -m "Month 4 complete"