Weekly Review — Month 5 · Week 2 (Days 120–126)¶
📅 The Week in One Line¶
Turned a bare gRPC service into a production-shaped one: interceptors (logging, recovery, auth), TLS transport, REST transcoding, reflection/grpcurl, and hermetic bufconn testing.
✅ What I Completed¶
- Day 120 — Logging & recovery interceptors; chain order; named returns for
recover - Day 121 — Auth interceptors; metadata extraction;
UnauthenticatedvsPermissionDenied - Day 122 — TLS & secure transport; cert/CA/SAN trust model; mTLS
- Day 123 — grpc-gateway / REST transcoding;
google.api.httppath templates - Day 124 — Server reflection & grpcurl; health checking
- Day 125 — Testing gRPC over bufconn; asserting status codes; interceptors as unit-testable functions
- Day 126 — Week review + recall
- Stdlib examples:
interceptors,authmeta,tls,transcoding - Exercises solved: 3 (chain, metadata, pathtemplate) — all
go testgreen
💡 Lessons Learned¶
- An interceptor is just middleware:
func(ctx, req, info, handler) (resp, err). Composition order is the whole game — first argument toChainUnaryInterceptoris outermost. - Panic recovery REQUIRES named return values so the deferred
recover()can assignerr. - gRPC metadata keys are case-insensitive / lower-cased; use
md.Get("authorization"), not raw map indexing. - TLS verification is cert-chain + validity + ServerName/SAN match;
InsecureSkipVerifyis a trap, not a fix. Add the CA toRootCAsinstead. - grpc-gateway transcodes HTTP+JSON into RPCs via
{id}path templates and maps status codes back to HTTP. - Reflection makes a server self-describing for grpcurl — great in dev, risky in prod.
- bufconn gives in-memory, full-stack, fast tests; assert on
status.Code(err), never the error string.
💪 Strengths (what clicked)¶
- The middleware/onion mental model — it transferred straight from
net/httpmiddleware. - The TLS trust model finally feels concrete after generating a self-signed cert and watching verification fail without trust.
- Table-driven tests for the chain ordering made the "first = outermost" rule stick.
🧩 Weaknesses (what's still fuzzy)¶
- Streaming interceptors (wrapping
ServerStream) — only read about them, didn't build one. - JWT verification internals (signature/exp/audience) — treated tokens as opaque keys.
- Cert rotation without downtime (
GetCertificatecallback).
🔁 Spaced-Repetition Re-quiz (topics from earlier weeks)¶
- Q: (Day 118) A gRPC handler returns
codes.DeadlineExceeded— what HTTP status does grpc-gateway map it to?A
504 Gateway Timeout. - Q: (Month 2 channels) What does a receive from a closed channel return?
A
The element type's zero value immediately, withok == falsein the comma-ok form. Closing is a broadcast. - Q: (Month 1 slices) Why can
appendmutate a slice you passed to another function?A
Slices share a backing array; if there's spare capacity,appendwrites in place and both headers see the change. Copy or use 3-index slicing to isolate. - Q: (Month 4 errors) How do you check for a sentinel error through wrapping?
A
errors.Is(err, ErrTarget); wrap with%wso the chain is walkable. Useerrors.Asto extract a typed error. - Q: (Day 121) Why must request-scoped identity ride the context, not a package variable?
A
Context is per-request and cancellation-aware; a package var is shared across concurrent RPCs and would leak/clash identities.
🎯 Action Items¶
- Build one streaming interceptor that wraps
ServerStreamand logs each message. - Add an mTLS variant of the TLS example notes (
RequireAndVerifyClientCert). - Write a bufconn test that injects metadata and asserts the auth interceptor rejects a bad token.
- Verify a real JWT (signature +
exp) instead of an opaque token lookup.
🚀 Next Week Goals¶
- Service architecture: project layout (
cmd/,internal/), dependency injection, and config loading. - Graceful shutdown and lifecycle management for a gRPC + gateway binary.
- Wiring interceptors, TLS, health, and reflection into one cohesive service skeleton.
📊 Metrics¶
| Hours | Days hit | Exercises | Commits | Avg confidence |
|---|---|---|---|---|
| 10.5 | 7/7 | 3 | 7 | 3.⅘ |
Suggested commit: docs(journal): week 2 review