Ship Go services faster, safely.

hwm-go-utils is the shared toolkit behind HiWay Media's Go services: a CRUD REST API from a single struct, Keycloak JWT auth that fails closed, and clients for Keycloak, Nomad, NATS, MySQL and Redis — hardened, tested, and ready for production.

go get github.com/HiWay-Media/hwm-go-utils@latest

Get started Browse packages GitHub

Go build Go test Go version License

Why hwm-go-utils

From zero to a protected REST API

One struct, one database, one line per resource:

package main

import (
	"os"

	"github.com/HiWay-Media/hwm-go-utils/api/generic"
	"github.com/HiWay-Media/hwm-go-utils/api/middlewares"
	"github.com/HiWay-Media/hwm-go-utils/db"
	"github.com/HiWay-Media/hwm-go-utils/log"
	"github.com/gofiber/fiber/v2"
)

type Product struct {
	ID    uint    `json:"id" gorm:"primaryKey"`
	Name  string  `json:"name" validate:"nonzero"`
	Price float64 `json:"price"`
}

func main() {
	logger := log.GetLogger("info")

	database, err := db.Open("app", "secret", "mysql", 3306, "shop", "5", "20")
	if err != nil {
		logger.Fatalf("database: %v", err) // the error never contains the password
	}

	app := fiber.New()
	// realm public key from Keycloak → Realm settings → Keys → RS256 → Public key
	api := app.Group("/api", middlewares.JwtProtected(os.Getenv("KEYCLOAK_PUBLIC_KEY"),
		middlewares.WithIssuer("https://sso.example.com/realms/shop"),
	))

	// GET /api/products, GET /api/products/:id, POST /api/products, DELETE /api/products/:id
	generic.SetEndpoints[Product]("products", api, database, logger)

	logger.Fatal(app.Listen(":8080"))
}

Walk through it step by step →

How it fits together

flowchart LR
    S(["Your Go service"]) --> L
    subgraph L["hwm-go-utils"]
        direction TB
        API["api/* · CRUD · JWT · client"]
        KC["keycloak"]
        NO["nomad"]
        NA["nats_helper"]
        DB["db"]
        RD["redis · keydb"]
        LG["log · utils"]
    end
    API --> MySQL
    API -. public key .-> Keycloak
    DB --> MySQL[("MySQL")]
    KC --> Keycloak(["Keycloak"])
    NO --> Nomad(["Nomad API"])
    NA --> NATS(["NATS · JetStream"])
    RD --> Redis[("Redis · KeyDB")]

Packages

Package What you get Guide
api/generic Generic CRUD handlers, service and store for any GORM model Generic CRUD
api/middlewares JwtProtected, RoleCheck, safe claim getters JWT middleware
api/client Minimal JSON REST client with bearer auth HTTP client
api/models Standard OK / KO response envelopes Responses
keycloak Login, tokens, users, groups, realms, client roles Keycloak
nomad Job definitions, allocations, scale, restart, run, delete Nomad
nats_helper Resilient NATS connection and JetStream context NATS
db MySQL via GORM with pool limits Database
redis, keydb Cluster and single-node Redis clients Redis & KeyDB
log zap console logger configured from a string Logging
utils/* Strings, slices, maps, ints, dates, conversions, files Utilities

Requires Go 1.26 or later. Upgrading from v0.6.x? Read the upgrade guide first — a few defaults changed for the better.