Files
homelab-frontend/tasks/0.2-route-configuration.md
T
Story Crater BotandClaude Opus 5 058f11cf2b
CI / Test (push) Canceled after 0s
CI / Vet (push) Canceled after 0s
CI / Build (push) Canceled after 0s
CI / Security (govulncheck) (push) Canceled after 0s
chore: initial commit of Go API gateway
Baseline for the Kong replacement on api.riotpiao.com. Brings the working
tree under version control for the first time: gateway source, the task
board that drives the agent runs, test fixtures, and K8s manifests.

Anchor the gateway ignore rule to the repo root. Unanchored, "gateway"
also matched the cmd/gateway/ source directory, so the program entrypoint
was excluded from every commit.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-19 20:54:34 -07:00

1.5 KiB

0.2 — Declarative route configuration (RED)

Phase: 0 — Foundations Stage: RED

  • Routes and upstreams are declared in YAML loaded from a file path at startup
  • Each upstream declares: address, path rewrite, connect timeout, read timeout, write timeout, maximum request body size, and an auth-required flag
  • Every one of those fields is explicit — no silent defaults for timeouts, body caps or auth
  • A config missing any required field fails startup with a non-zero exit and a message naming the offending route and field
  • A config with a malformed duration, an unparseable address, or a duplicate route key fails startup the same way
  • A valid config round-trips: every declared route is present in the loaded route table
  • Loading is startup-only — no API-server watch, no CRD, no Kubernetes client

Configuration lives in git and is mounted as a ConfigMap synced by Argo. It is deliberately not a CRD: a CRD would require the gateway to watch the API server, which needs RBAC and contradicts the invariant that the gateway holds no cluster credentials. It is also the exact indirection being retired with Kong, whose routing table was split across six KongPlugin CRs, seven Ingresses and a Helm values file.

A gateway that starts with a silently dropped route is worse than one that refuses to start.

Verify

go test ./internal/config/... -v
# expected: passes — valid fixtures load with all routes present; each invalid fixture
# returns an error naming the offending route and field, and none of them load partially