go-modules

module
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 14, 2026 License: MIT

README

common-go

Shared platform library for Tupic Go services. Capability-based packages — not a layered application: each package is one platform concern with its contract and implementation together.

Package Concern
apperror Application error type mapped to HTTP statuses
authentication, authentication/iam, authentication/dummy Authentication: bearer token → identity
authorization Actor security context + scope/permission policy
clock, logger, random, validator Core contracts + implementations
config Layered JSON config loading with env overrides
echo Echo HTTP stack: error handler, server, middlewares, guards
event Domain events + in-process sync bus
nats NATS JetStream connection, routing, subscribers, DLQ
outbox Transactional outbox storage + NATS relay
pagination Cursor pagination types
persistence DB connector, migrator, unit of work
queue Work-queue contract + outbox-backed implementation
sentry Sentry init with shutdown flush
storage, storage/s3 File storage contract + S3 backend
testutil Test helpers

config, echo, nats, and sentry wrap a same-named third-party package (labstack echo, nats.go, sentry-go, config loading) that services also import in the same files. Where both appear in one file, alias the upstream import (labecho, natslib); the wrapper keeps the clean name.

Auth architecture

Authentication (authentication) answers who is calling; authorization (authorization) answers may they do this. They meet in authorization.Actor.

HTTP request with "Authorization: Bearer <token>"
    │
    ▼
echo.AuthMiddleware ───────────────── marks admin routes for role hydration,
    │                                 continues anonymously on bad tokens
    ▼
authentication.Authenticator[U].Authenticate    U = the service's user entity
    │
    ├─ iam driver (production):       validate JWT against JWKS (RS256,
    │                                 issuer, expiry; refetch rate-limited)
    │                                   ├─ service-account token → service Actor, no user
    │                                   └─ user token → UserResolver[U] (service-owned
    │                                      find-or-provision) → user Actor + *U
    │
    └─ dummy driver (tests/local):    token is base64 JSON Actor
    │
    ▼
Actor + user stored in request context
    │
    ▼
echo.RequireUser / RequireAdmin / RequireService   (route guards)
    │
    ▼
use case calls authorization.Authorizer.Authorize(actor, permissions...)
                                      (scope + permission policy: exact,
                                       admin-prefixed, or service wildcard)
What a service implements

Only its user resolver — everything else is shared:

// 1. The resolver: validated claims → the service's user entity.
type userResolver struct{ /* repo, clock, ... */ }

func (r *userResolver) Resolve(ctx context.Context, c *iam.Claims) (*myservice.User, error) {
    // find-or-provision; this is where per-service rules live
}

// 2. Wiring: one call.
authn, err := authentication.New(
    authentication.Config{Driver: cfg.Auth.Driver, IAM: iam.Config{
        Issuer: cfg.Auth.Issuer, JwksURL: cfg.Auth.JwksURL, ServiceName: "MyService",
    }},
    newUserResolver(...),
    repo.FindByID, // dummy-driver lookup
)

// 3. HTTP middleware: one struct.
echo.AuthMiddleware(echo.AuthConfig[myservice.User]{
    Authenticate:    authn.Authenticate,
    WithUser:        myservice.ContextWithUser,
    AdminPathPrefix: "/myservice/v1/admin",
})
Extending
  • Custom driver (API keys, another IdP): implement the one-method authentication.Authenticator[U] interface — or wrap a closure in authentication.Func[U] — and skip authentication.New. The middleware and guards only see the interface.
  • Function-only resolver: iam.UserResolverFunc[U] adapts a closure.
  • Test wiring: iam.WithHTTPClient injects an in-process round-tripper; iam.WithJWKSCooldown tunes (or disables) the JWKS refetch rate limit.
  • Permissions: fully qualified "<service>:<resource>.<action>" (e.g. "assets:assets.write"). The shared TokenAuthorizer matches the exact form, the admin:-prefixed form, and service wildcards (assets:*, admin:assets:*).

Consumption pattern

Services keep thin facade packages re-exporting shared contracts via type aliases (internal/domain/common, internal/application/port, …) so domain and application code never imports common-go directly, plus one bootstrap/modules.go mapping service config to the narrow shared config types (logger.Config, nats.Config, persistence/config.Config, …).

Until the GitHub repo exists, services use replace github.com/tupicapp/common-go => ../common-go.

License

Released under the MIT License.

Directories

Path Synopsis
Package app provides shared application lifecycle logic and bootstrap helpers.
Package app provides shared application lifecycle logic and bootstrap helpers.
Package apperror defines the platform-wide application error type used to map domain and application failures to transport-level responses.
Package apperror defines the platform-wide application error type used to map domain and application failures to transport-level responses.
Package auth provides authentication for Tupic services: turning a bearer credential into an identity.
Package auth provides authentication for Tupic services: turning a bearer credential into an identity.
dummy
Package dummy provides an Authenticator that decodes the bearer token as a base64-encoded JSON Actor.
Package dummy provides an Authenticator that decodes the bearer token as a base64-encoded JSON Actor.
iam
Package iam authenticates requests using Tupic IAM (Keycloak) JWTs.
Package iam authenticates requests using Tupic IAM (Keycloak) JWTs.
Package clock provides the Clock contract to provide time with testability.
Package clock provides the Clock contract to provide time with testability.
Package config loads layered JSON configuration files with environment variable overrides into a service-defined config struct.
Package config loads layered JSON configuration files with environment variable overrides into a service-defined config struct.
Package echo provides the shared Echo HTTP stack: instance assembly, apperror-aware error handling, request logging, Sentry integration, the HTTP server lifecycle, and actor guard middlewares.
Package echo provides the shared Echo HTTP stack: instance assembly, apperror-aware error handling, request logging, Sentry integration, the HTTP server lifecycle, and actor guard middlewares.
Package event defines the domain-event contract and the in-process synchronous event bus shared by all Tupic services.
Package event defines the domain-event contract and the in-process synchronous event bus shared by all Tupic services.
Package logger provides the Logger contract plus zap, memory, and noop implementations.
Package logger provides the Logger contract plus zap, memory, and noop implementations.
Package nats provides the NATS JetStream connection, subject routing, and event/queue subscribers shared by all Tupic services.
Package nats provides the NATS JetStream connection, subject routing, and event/queue subscribers shared by all Tupic services.
Package outbox implements the Transactional Outbox pattern: events are stored in the caller's DB transaction and a relay ships them to NATS.
Package outbox implements the Transactional Outbox pattern: events are stored in the caller's DB transaction and a relay ships them to NATS.
Package pagination defines shared cursor-pagination types.
Package pagination defines shared cursor-pagination types.
Package persistence wires the database connector, migrator, and unit of work shared by all Tupic services.
Package persistence wires the database connector, migrator, and unit of work shared by all Tupic services.
config
Package config holds the persistence configuration types in a leaf package so the connector and migrator can import them without cycles.
Package config holds the persistence configuration types in a leaf package so the connector and migrator can import them without cycles.
connector
Package connector opens and supervises the SQL connection pool and its GORM handle.
Package connector opens and supervises the SQL connection pool and its GORM handle.
migrator
Package migrator selects the migration driver from configuration.
Package migrator selects the migration driver from configuration.
migrator/contract
Package contract defines the migration driver contract.
Package contract defines the migration driver contract.
migrator/postgres
Package postgres implements the migration contract with golang-migrate.
Package postgres implements the migration contract with golang-migrate.
uow
Package uow provides the UnitOfWork contract and its GORM transaction implementation, plus the context plumbing repositories use to join an ambient transaction.
Package uow provides the UnitOfWork contract and its GORM transaction implementation, plus the context plumbing repositories use to join an ambient transaction.
Package queue defines the platform work-queue contract and its outbox-backed implementation.
Package queue defines the platform work-queue contract and its outbox-backed implementation.
Package random provides the Random contract plus a crypto/rand-backed implementation.
Package random provides the Random contract plus a crypto/rand-backed implementation.
Package sentry initializes the Sentry SDK with a shutdown flush hook.
Package sentry initializes the Sentry SDK with a shutdown flush hook.
Package storage defines the platform file-storage contract.
Package storage defines the platform file-storage contract.
s3
Package s3 implements the storage contract with AWS S3 (or a compatible API such as LocalStack/MinIO).
Package s3 implements the storage contract with AWS S3 (or a compatible API such as LocalStack/MinIO).
Package testutil provides small helpers shared by service test suites.
Package testutil provides small helpers shared by service test suites.
Package utility provides general-purpose helper functions shared across Tupic services.
Package utility provides general-purpose helper functions shared across Tupic services.
Package validator provides the Validator contract plus a go-playground/validator implementation that maps violations to apperror.
Package validator provides the Validator contract plus a go-playground/validator implementation that maps violations to apperror.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL