Modulis ir konfigūracija
Pirma — modulis. go.mod — ne failas, kurį rašai ranka; jį tvarko Go įrankiai. go mod init jį sukuria, o go get prideda priklausomybes. Paleisk:
go mod init github.com/programuoki/signflow
go get github.com/go-chi/chi/v5 # vienintelė šios pamokos priklausomybė: maršrutizatorius
go.mod auga kartu su programa — Templ prisijungs 2 pamokoje, Postgres ir goose — 3-ioje — bet auginsi jį su go get, o ne redaguodamas, tad jis lieka už kodo stulpelio ribų. (go mod tidy palaiko netiesiogines priklausomybes tvarkingas.)
Dabar tikras failas — internal/config/config.go (kodo stulpelyje) — konfigūracija iš aplinkos. Visos programos taisyklė: numatytos reikšmės, leidžiančios go run be jokio paruošimo dev aplinkoje, bet kiekviena tikra reikšmė produkcijoje ateina iš aplinkos.
func Load() (Config, error) {
cfg := Config{
Port: getenv("PORT", "8080"), // Railway nustato $PORT
Env: getenv("APP_ENV", "dev"),
BaseURL: os.Getenv("BASE_URL"),
}
if cfg.BaseURL == "" {
cfg.BaseURL = "http://localhost:" + cfg.Port
}
return cfg, nil
}
Atkreipk dėmesį: Config prasideda mažas — trys laukai — o IsProd() pagalbininkas skaito Env. Vėlesnės pamokos prideda laukų (kitą pamoką — duomenų bazės URL, 4-oje — sesijos raktą), o ne perrašo failo. Load jau grąžina error, nors kol kas niekas nelūžta: produkcija pridės privalomų reikšmių patikras, o stabili parašo forma dabar reiškia, kad vėlesnės pamokos šią funkciją tik papildys.
Kodėl
internal/? Go paketą pointernal/gali importuoti tik kodas iš to paties modulio. Tai kompiliatoriaus užtikrintas „privatumas": niekas iš išorės negaliimport github.com/programuoki/signflow/internal/config. Viskas, išskyruscmd/, gyvena pointernal/.