chore: update go.mod dependencies and versions chore: update go.sum with new dependency versions scripts: add coverage check script scripts: add release notes generation script test: refactor tests to use goconvey for assertions test: enhance webserver tests with additional cases and goconvey fix: improve error logging in web server start and stop methods |
||
|---|---|---|
| .githooks | ||
| config | ||
| docs | ||
| scripts | ||
| test | ||
| web | ||
| .drone.yml | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| AGENTS.md | ||
| LICENSE | ||
| README.md | ||
| go.mod | ||
| go.sum | ||
| vulncheck.json | ||
README.md
go-lib/micro
Lightweight Go helper library for building microservices with:
- Opinionated HTTP/HTTPS server bootstrap around chi.
- Built-in health and readiness endpoints.
- Convention-based YAML config loading with defaults.
Installation
go get scm.yoorie.de/go-lib/micro
Packages
- config/configfiles.go: configuration discovery and loading.
- web/server.go: HTTP/HTTPS server bootstrap and lifecycle.
- web/health.go: health-check worker and endpoint payloads.
Configuration Loading
The config package supports:
- Default values via struct tags.
- Loading from an explicit file path.
- Optional convention lookup based on an AppName method.
Lookup order for convention-based loading:
- Executable directory with executable-name.yml
- Executable directory with executable-name.yaml
- User-local file in home directory under .myservice/config
- Global config path returned by util.GetGlobalConfigurationFile(appName, "config")
Example:
package main
import (
"log"
"scm.yoorie.de/go-lib/micro/config"
)
type ServiceConfig struct {
Port int `default:"7080" yaml:"port"`
Host string `default:"0.0.0.0" yaml:"host"`
}
// Optional: enables convention-based config file discovery.
func (c *ServiceConfig) AppName() string {
return "myservice"
}
func main() {
cfg := &ServiceConfig{}
// Option A: explicit file
if err := config.LoadConfigurationFromFile(cfg, "config.yml"); err != nil {
log.Fatal(err)
}
// Option B: automatic discovery using AppName()
// if err := config.LoadConfiguration(cfg); err != nil {
// log.Fatal(err)
// }
}
Web Server
The web package wraps chi and starts:
- HTTP server when SslPort is not set.
- HTTPS server and separate HTTP health endpoint server when SslPort is set.
Default health endpoints:
- /health/healthz
- /health/readyz
Example:
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
"scm.yoorie.de/go-lib/micro/web"
)
type Message struct {
Text string `json:"text"`
}
func routes() *chi.Mux {
r := chi.NewRouter()
r.Get("/hello", func(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, Message{Text: "hello"})
})
return r
}
func main() {
cfg := &web.WebServerConfiguration{
Host: "0.0.0.0",
Port: 7080,
}
server, err := web.NewWebServer(cfg)
if err != nil {
panic(err)
}
// Optional custom health function.
server.HealthCheck = func() (bool, string) {
return true, ""
}
server.Mount("/api", routes())
if err := server.Start(); err != nil {
panic(err)
}
// Block until interrupt.
server.Join()
}
Development
Run unit tests:
go test ./...
Run vet:
go vet ./...
Run coverage like CI:
mkdir -p .build
go test -v -coverprofile .build/coverage.out -coverpkg=./config,./web ./...
go tool cover -func .build/coverage.out
bash scripts/check-coverage.sh .build/coverage.out 80
Run vulnerability scan:
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
CI and Release
Drone pipeline is defined in .drone.yml and includes:
- Tests
- Coverage gate (80%)
- go vet
- govulncheck
- Tag-based release notes and packaging
For the complete release workflow see docs/RELEASING.md.
Project Docs
License
MIT, see LICENSE.
