mirror of
https://github.com/MedUnes/go-kata.git
synced 2026-03-12 21:55:53 +07:00
Kata 18: embed.FS Dev/Prod Switch Without Handler Forks
Target Idioms: embed, io/fs, Build Tags, fs.Sub, Same Handler Code Path
Difficulty: 🟡 Intermediate
🧠 The "Why"
Embedding assets is great for production (single binary), but terrible for frontend iteration if every CSS tweak needs a rebuild. Idiomatic Go solves this with:
- compile-time selection via build tags
- a shared
fs.FSabstraction so handler code doesn’t branch on “dev/prod”.
🎯 The Scenario
You run a small internal dashboard:
- Prod: ship a single binary (assets embedded).
- Dev: designers update
static/andtemplates/live without recompiling.
🛠 The Challenge
Create a server that serves:
- templates from
templates/ - static assets from
static/
1. Functional Requirements
GET /renders an HTML template.GET /static/...serves static files.- Dev mode serves from disk; prod mode serves embedded.
- Handler code is identical in both modes.
2. The "Idiomatic" Constraints (Pass/Fail Criteria)
- Build tags: two files:
assets_dev.gowith//go:build devassets_prod.gowith//go:build !dev
- Return
fs.FS:func Assets() (templates fs.FS, static fs.FS, err error) - Use
fs.Sub: exported FS must have clean roots (nostatic/static/...path bugs). - No runtime env checks in handlers: mode selection must be compile-time.
- Single
http.FileServersetup: no duplicated handler logic for dev vs prod.
🧪 Self-Correction (Test Yourself)
-
Live Reload
- Build with
-tags dev. - Modify a CSS file and refresh.
- Pass: change shows without rebuild.
- Build with
-
Binary Portability
- Build without tags.
- Delete
static/andtemplates/from disk. - Pass: server still serves assets/templates.
-
Prefix Correctness
- Request
/static/app.css. - Pass: works in both modes (no 404 due to prefix mismatch).
- Request