go-micro-framework
Lightweight framework for bootstrapping Go microservices with:
- HTTP APIs based on Huma and net/http
- configuration via file or environment variables
- Prometheus metrics
- actuator endpoints
- optional listeners for NATS JetStream, Kafka, or RabbitMQ
- helper for PostgreSQL initialization with GORM
The module is designed to be imported from other Go repositories.
Installation
go get github.com/sviviani/go-micro-framework
The current module path is github.com/sviviani/go-micro-framework.
Available Packages
- appconfig: configuration loading with Viper and environment overrides
- appdb: PostgreSQL bootstrap with GORM auto-migration
- appmessaging: listener bootstrap for NATS, Kafka, or RabbitMQ
- application: HTTP bootstrap, graceful shutdown, actuator, metrics
- configuration: configuration structs and container memory limit utilities
- database: PostgreSQL + GORM helpers
- messaging: factory and listeners for NATS, Kafka, RabbitMQ
- dto: generic request/response wrappers
- utils: parsing, error mapping, and application tracing
Quick Start
package main
import (
"log"
"net/http"
"github.com/sviviani/go-micro-framework/appconfig"
"github.com/sviviani/go-micro-framework/application"
)
func main() {
cfg := appconfig.MustLoad(nil)
app, err := application.New(
cfg,
application.Metadata{
APITitle: "Orders API",
APIVersion: "1.0.0",
Name: "orders-service",
Version: "1.0.0",
Environment: "dev",
SwaggerPath: "./swagger-ui",
},
application.Options{
RegisterRoutes: func(mux *http.ServeMux) {
mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"ok"}`))
})
},
},
)
if err != nil {
log.Fatal(err)
}
if err := app.Run(); err != nil {
log.Fatal(err)
}
}
Configuration
appconfig.Load and appconfig.MustLoad look for a file named configuration in these paths:
- .
- config/
- /etc/app/
- $HOME/.app
Formats supported by Viper are supported, for example configuration.yaml, configuration.json, or configuration.toml.
Environment variables use the APP_ prefix.
Examples:
export APP_PORT=8080
export APP_LOGLEVEL=debug
export APP_DATABASE_HOST=localhost
export APP_DATABASE_PORT=5432
export APP_DATABASE_NAME=orders
export APP_DATABASE_USER=orders_app
export APP_DATABASE_PASSWORD=secret
export APP_BROKER_ENABLED=true
export APP_BROKER_TYPE=nats
Configuration Structure
port: 8080
logLevel: info
database:
host: localhost
port: 5432
name: orders
user: orders_app
password: secret
sslMode: disable
timezone: UTC
broker:
enabled: true
type: nats
nats:
url: nats://localhost:4222
stream: ORDERS
topic: orders.created
durableConsumer: orders-service
Database
To initialize PostgreSQL with GORM auto-migration, you can use appdb.InitPostgres:
db, err := appdb.InitPostgres(cfg, []any{
&Order{},
&OrderLine{},
})
if err != nil {
log.Fatal(err)
}
The returned value implements the minimal interface used by the framework:
- PingContext(context.Context) error
- Close() error
This also allows you to provide your own custom implementation to application.New.
The application package stays focused on the HTTP lifecycle. Configuration, DB, and broker setup live in dedicated packages, so consumers only import what they actually need. Huma integration remains available as an optional helper through application.RegisterHumaRoutes.
Example Consumer
A complete consumer microservice is included in example/consumer.
Quick check:
cd example/consumer
go test ./...
Messaging
appmessaging.Init uses messaging.NewListener internally and creates the listener based on broker.type:
If broker.enabled=false, the listener is not created and the framework continues to run as an HTTP-only service.
Each adapter supports either a single configuration or a list of named subscriptions.
Minimal example:
listener, err := appmessaging.Init(cfg, func(topic string, payload []byte) error {
return nil
})
if err != nil {
log.Fatal(err)
}
Included Endpoints
The bootstrap registers automatically:
- /metrics
- /actuator/*
- /swagger-ui/* if SwaggerPath is set
The /actuator/shutdown endpoint returns 202 Accepted and triggers graceful shutdown for the server, broker listener, and database.
Testing
The repository includes unit tests for:
- bootstrap and application configuration
- database helpers
- messaging factory and subscription resolution
- generic DTOs
- parsing utilities, error mapping, and tracing
Run:
go test ./...
Release
The release and API compatibility checklist is in RELEASE.md.