189 lines
4.0 KiB
Markdown
189 lines
4.0 KiB
Markdown
# go-lib/micro
|
|
|
|
[](https://drone.yoorie.de/go-lib/micro)
|
|
[](https://scm.yoorie.de/go-lib/micro/releases)
|
|
[](https://scm.yoorie.de/go-lib/micro/src/branch/main/LICENSE)
|
|
|
|
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
|
|
|
|
```bash
|
|
go get scm.yoorie.de/go-lib/micro
|
|
```
|
|
|
|
## Packages
|
|
|
|
- [config/configfiles.go](config/configfiles.go): configuration discovery and loading.
|
|
- [web/server.go](web/server.go): HTTP/HTTPS server bootstrap and lifecycle.
|
|
- [web/health.go](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:
|
|
|
|
1. Executable directory with executable-name.yml
|
|
2. Executable directory with executable-name.yaml
|
|
3. User-local file in home directory under .myservice/config
|
|
4. Global config path returned by util.GetGlobalConfigurationFile(appName, "config")
|
|
|
|
Example:
|
|
|
|
```go
|
|
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:
|
|
|
|
```go
|
|
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:
|
|
|
|
```bash
|
|
go test ./...
|
|
```
|
|
|
|
Run vet:
|
|
|
|
```bash
|
|
go vet ./...
|
|
```
|
|
|
|
Run coverage like CI:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
go install golang.org/x/vuln/cmd/govulncheck@latest
|
|
govulncheck ./...
|
|
```
|
|
|
|
## CI and Release
|
|
|
|
Drone pipeline is defined in [.drone.yml](.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](docs/RELEASING.md).
|
|
|
|
## Project Docs
|
|
|
|
- [docs/DEFINITION_OF_DONE.md](docs/DEFINITION_OF_DONE.md)
|
|
- [docs/RELEASING.md](docs/RELEASING.md)
|
|
|
|
## License
|
|
|
|
MIT, see [LICENSE](LICENSE).
|