micro/README.md

189 lines
4.0 KiB
Markdown
Raw Normal View History

# go-lib/micro
2023-03-08 09:54:35 +00:00
[![Build Status](https://drone.yoorie.de/api/badges/go-lib/micro/status.svg)](https://drone.yoorie.de/go-lib/micro)
[![Release](https://raster.shields.io/badge/dynamic/json.png?label=release&url=https://scm.yoorie.de/api/v1/repos/go-lib/micro/releases&query=$[0].tag_name)](https://scm.yoorie.de/go-lib/micro/releases)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://scm.yoorie.de/go-lib/micro/src/branch/main/LICENSE)
2023-03-08 09:54:35 +00:00
Lightweight Go helper library for building microservices with:
2023-03-08 09:54:35 +00:00
- Opinionated HTTP/HTTPS server bootstrap around chi.
- Built-in health and readiness endpoints.
- Convention-based YAML config loading with defaults.
2023-03-08 09:54:35 +00:00
## Installation
2023-03-08 09:54:35 +00:00
```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).