frame

package module
v2.0.2 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2026 License: Apache-2.0 Imports: 54 Imported by: 0

README

Frame

Build Status Ask DeepWiki

A fast, extensible Golang framework with a clean plugin-based architecture.

Frame helps you spin up HTTP and gRPC services with minimal boilerplate while keeping strong runtime management, observability, and portable infrastructure via Go Cloud.

Features

  • HTTP and gRPC servers with built-in lifecycle management
  • Datastore setup using GORM with migrations and multi-tenancy
  • Queue publish/subscribe (Go Cloud drivers: mem://, nats://, etc.)
  • Cache manager with multiple backends
  • OpenTelemetry tracing, metrics, and logs
  • OAuth2/JWT authentication and authorization adapters
  • Worker pool for background tasks
  • Localization utilities

Install

go get -u github.com/pitabwire/frame/v2

Minimal Example

package main

import (
    "context"
    "net/http"

    "github.com/pitabwire/frame/v2"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Frame says hello"))
    })

    _, svc := frame.NewService(
        frame.WithName("hello"),
        frame.WithHTTPHandler(http.DefaultServeMux),
    )

    _ = svc.Run(context.Background(), ":8080")
}

Documentation

Docs Site (MkDocs)

pip install mkdocs mkdocs-material
mkdocs serve

Development

To run tests, start the Docker Compose file in ./tests, then run:

go test -json -cover ./...

Contributing

If Frame helped you, please consider starring the repo and sharing it.

We’re actively looking for contributions that make Frame easier to use and more productive for Go teams. Examples:

  • Improve onboarding guides or add real-world examples
  • Add new Go Cloud drivers (queue, cache, datastore)
  • Add middleware, interceptors, or CLI tooling
  • Expand testing utilities or reference architectures

AI-assisted contributions are welcome. If you use AI tools, please verify behavior locally and include tests where relevant.

Open an issue or PR with your idea — even small improvements make a big difference.

Documentation

Index

Constants

View Source
const ManifestRegistrationPath = "/_internal/register/permissions"

ManifestRegistrationPath is the default HTTP path for the internal permission manifest registration endpoint on the tenancy service.

View Source
const ManifestRegistrationURLEnvVar = "PERMISSIONS_REGISTRATION_URL"

ManifestRegistrationURLEnvVar is the environment variable that provides the full URL for permission manifest registration. Services set this to point at the tenancy service's internal registration endpoint.

Variables

View Source
var ErrHTTPServerConfigRequired = errors.New("configuration must implement config.ConfigurationHTTPServer")
View Source
var ErrHealthCheckFailed = errors.New("health check failed")

Functions

func ErrorIsNotFound

func ErrorIsNotFound(err error) bool

ErrorIsNotFound checks if an error represents a "not found" condition. It handles multiple error types: - Database errors: gorm.ErrRecordNotFound, sql.ErrNoRows (via ErrorIsNoRows) - gRPC errors: codes.NotFound - Generic errors: error messages containing "not found" (case-insensitive).

func FormatNamespaceDisplay

func FormatNamespaceDisplay(namespace string) string

FormatNamespaceDisplay returns a human-readable name from a service namespace identifier (e.g. "service_profile" → "Profile").

func SubmitJob

func SubmitJob[T any](ctx context.Context, s *Service, job workerpool.Job[T]) error

SubmitJob used to submit jobs to our worker pool for processing. Once a job is submitted the end user does not need to do any further tasks One can ideally also wait for the results of their processing for their specific job by listening to the job's ResultChan.

func ToContext

func ToContext(ctx context.Context, service *Service) context.Context

ToContext pushes a service instance into the supplied context for easier propagation.

Types

type Checker

type Checker interface {
	CheckHealth() error
}

Checker wraps the CheckHealth method.

CheckHealth returns nil if the resource is healthy, or a non-nil error if the resource is not healthy. CheckHealth must be safe to call from multiple goroutines.

type CheckerFunc

type CheckerFunc func() error

CheckerFunc is an adapter type to allow the use of ordinary functions as health checks. If f is a function with the appropriate signature, CheckerFunc(f) is a Checker that calls f.

func (CheckerFunc) CheckHealth

func (f CheckerFunc) CheckHealth() error

CheckHealth calls f().

type HealthCheckResult

type HealthCheckResult struct {
	Name   string `json:"name"`
	Status string `json:"status"`
	Error  string `json:"error,omitempty"`
}

HealthCheckResult holds the result of an individual health checker.

type HealthResponse

type HealthResponse struct {
	Service    string              `json:"service"`
	Version    string              `json:"version"`
	Repository string              `json:"repository,omitempty"`
	Commit     string              `json:"commit,omitempty"`
	BuildDate  string              `json:"build_date,omitempty"`
	Uptime     string              `json:"uptime"`
	Status     string              `json:"status"`
	Checks     []HealthCheckResult `json:"checks"`
}

HealthResponse is the JSON structure returned by the health check endpoint.

type NamedChecker

type NamedChecker interface {
	Name() string
}

NamedChecker is an optional interface that a Checker can implement to provide a human-readable name in health check responses.

type OPLSpec

type OPLSpec struct {
	Namespace string
	Data      []byte
}

OPLSpec holds an OPL namespace definition registered by a service.

type Option

type Option func(ctx context.Context, service *Service)

func WithBackgroundConsumer

func WithBackgroundConsumer(deque func(_ context.Context) error) Option

WithBackgroundConsumer sets a background consumer function for the worker pool.

func WithCache

func WithCache(name string, rawCache cache.RawCache) Option

WithCache adds a raw cache with the given name to the service.

func WithCacheManager

func WithCacheManager() Option

WithCacheManager adds a cache manager to the service.

func WithConfig

func WithConfig(cfg any) Option

WithConfig Option that helps to specify or override the configuration object of our service.

func WithDatastore

func WithDatastore(opts ...pool.Option) Option

func WithDatastoreConnection

func WithDatastoreConnection(postgresqlConnection string, readOnly bool) Option

WithDatastoreConnection Option method to store a connection that will be utilized when connecting to the database.

func WithDatastoreConnectionWithName

func WithDatastoreConnectionWithName(
	name string,
	postgresqlConnection string,
	readOnly bool,
	opts ...pool.Option,
) Option

func WithDatastoreConnectionWithOptions

func WithDatastoreConnectionWithOptions(name string, opts ...pool.Option) Option

func WithDatastoreManager

func WithDatastoreManager() Option

WithDatastoreManager creates and initializes a datastore manager with the given options. This is the low-level function that should rarely be called directly - use WithDatastore instead.

func WithDebugEndpoints

func WithDebugEndpoints() Option

WithDebugEndpoints enables AI-friendly introspection endpoints.

func WithDebugEndpointsAt

func WithDebugEndpointsAt(basePath string) Option

WithDebugEndpointsAt enables introspection endpoints at a custom base path.

func WithDriver

func WithDriver(driver server.Driver) Option

WithDriver setsup a driver, mostly useful when writing tests against the frame service.

func WithEnvironment

func WithEnvironment(environment string) Option

WithEnvironment specifies the environment the service will utilize.

func WithHTTPClient

func WithHTTPClient(opts ...client.HTTPOption) Option

WithHTTPClient configures the HTTP client used by the service. This allows customizing the HTTP client's behavior such as timeout, transport, etc.

func WithHTTPHandler

func WithHTTPHandler(h http.Handler) Option

WithHTTPHandler specifies an HTTP handlers that can be used to handle inbound HTTP requests.

func WithHTTPMiddleware

func WithHTTPMiddleware(middleware ...func(http.Handler) http.Handler) Option

WithHTTPMiddleware registers one or more HTTP middlewares. Middlewares wrap the application handler in the order supplied.

func WithHTTPRequestTimeout added in v2.0.2

func WithHTTPRequestTimeout(timeout time.Duration) Option

WithHTTPRequestTimeout adds a middleware that enforces a per-request timeout. The context will be canceled after the specified duration.

func WithHealthCheckPath

func WithHealthCheckPath(path string) Option

WithHealthCheckPath Option checks that the system is up and running.

func WithInMemoryCache

func WithInMemoryCache(name string) Option

WithInMemoryCache adds an in-memory cache with the given name.

func WithLogger

func WithLogger(opts ...util.Option) Option

WithLogger Option that helps with initialization of our internal dbLogger.

func WithName

func WithName(name string) Option

WithName specifies the name the service will utilize.

func WithOPL

func WithOPL(namespace string, data []byte) Option

WithOPL registers an OPL (Open Policy Language) namespace definition to be served at /_internal/opl/{namespace}. Multiple OPL specs can be registered for services that span multiple namespaces.

func WithOpenAPIBasePath

func WithOpenAPIBasePath(path string) Option

WithOpenAPIBasePath sets the base path used to serve OpenAPI specs. The default is /debug/frame/openapi.

func WithOpenAPISpec

func WithOpenAPISpec(name, filename string, content []byte) Option

WithOpenAPISpec registers a single OpenAPI spec with the service. Content should be provided from compile-time embedded assets.

func WithOpenAPISpecsFromFS

func WithOpenAPISpecsFromFS(f fs.FS, dir string) Option

WithOpenAPISpecsFromFS registers all .json OpenAPI specs from an embedded FS directory. Use //go:embed to provide the fs.FS at compile time.

func WithPermissionRegistration

func WithPermissionRegistration(sd protoreflect.ServiceDescriptor) Option

WithPermissionRegistration registers a service's permission manifest with the tenancy service. The manifest (namespace, permissions, role bindings) is extracted from the proto service descriptor's service_permissions annotation using proto reflection.

Registration runs as a PreStartMethod whenever PERMISSIONS_REGISTRATION_URL is set and the proto descriptor carries a service_permissions extension. It fires once per process start, before the service begins serving traffic. The tenancy registration endpoint is an idempotent upsert keyed on namespace, so repeat registrations across pod restarts are safe and keep the tenancy.service_namespaces table in sync with whatever the running binary declares.

Earlier versions gated registration on DO_MIGRATION=true so that only the migration job published manifests. That coupling broke whenever a service's cmd/main.go short-circuited before svc.Run (typical pattern): the migration pod never reached the PreStartMethod, the regular pod was locked out by the gate, and the namespace was never registered. Decoupling from migration mode fixes that without forcing every consumer to invent glue around svc.Run.

The tenancy service URL is read from PERMISSIONS_REGISTRATION_URL. When unset, the option is a no-op — services that don't want to register can leave it unset in their environment.

Usage:

sd := profilepb.File_profile_v1_profile_proto.Services().ByName("ProfileService")
frame.WithPermissionRegistration(sd)

func WithPlugin

func WithPlugin(name string, opt Option) Option

WithPlugin wraps an option and registers its name for introspection.

func WithRegisterEvents

func WithRegisterEvents(evt ...events.EventI) Option

WithRegisterEvents registers events for the service. All events are unique and shouldn't share a name otherwise the last one registered will take precedence.

func WithRegisterPublisher

func WithRegisterPublisher(reference string, queueURL string) Option

WithRegisterPublisher Option to register publishing path referenced within the system.

func WithRegisterSubscriber

func WithRegisterSubscriber(reference string, queueURL string,
	handlers ...queue.SubscribeWorker) Option

WithRegisterSubscriber Option to register a new subscription handlers.

func WithTelemetry

func WithTelemetry(opts ...telemetry.Option) Option

WithTelemetry adds required telemetry config options to the service.

func WithTenancyProvider

func WithTenancyProvider(prov tenancy.Provider) Option

WithTenancyProvider overrides the default Postgres-RLS tenancy provider that WithDatastore wires by default. Pass nil to disable tenancy enforcement entirely (useful for tests).

May be passed before or after WithDatastore in the option list — WithDatastore resolves s.tenancyProvider at construction time, and the resolved provider flows through to pool.NewPool via opts.

func WithTranslation

func WithTranslation(translationsFolder string, languages ...string) Option

WithTranslation Option that helps to specify or override the configuration object of our service.

func WithVersion

func WithVersion(version string) Option

WithVersion specifies the version the service will utilize.

func WithWorkerPoolOptions

func WithWorkerPoolOptions(options ...workerpool.Option) Option

WithWorkerPoolOptions provides a way to set custom options for the ants worker pool. Renamed from WithAntsOptions and changed parameter type.

type RouteInfo

type RouteInfo struct {
	Method  string `json:"method"`
	Path    string `json:"path"`
	Handler string `json:"handler"`
}

type RouteLister

type RouteLister interface {
	Routes() []RouteInfo
}

type RouteRegistry

type RouteRegistry struct {
	// contains filtered or unexported fields
}

RouteRegistry wraps http.ServeMux and records registered routes for introspection.

func NewRouteRegistry

func NewRouteRegistry() *RouteRegistry

func (*RouteRegistry) Handle

func (r *RouteRegistry) Handle(pattern string, handler http.Handler)

func (*RouteRegistry) HandleFunc

func (r *RouteRegistry) HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))

func (*RouteRegistry) HandleRoute

func (r *RouteRegistry) HandleRoute(method, pattern, name string, handler func(http.ResponseWriter, *http.Request))

HandleRoute records method-aware routes for introspection.

func (*RouteRegistry) Routes

func (r *RouteRegistry) Routes() []RouteInfo

func (*RouteRegistry) ServeHTTP

func (r *RouteRegistry) ServeHTTP(w http.ResponseWriter, req *http.Request)

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service framework struct to hold together all application components An instance of this type scoped to stay for the lifetime of the application. It is pushed and pulled from contexts to make it easy to pass around.

func FromContext

func FromContext(ctx context.Context) *Service

func NewService

func NewService(opts ...Option) (context.Context, *Service)

NewService creates a new instance of Service with the name and supplied options. Internally it calls NewServiceWithContext and creates a background context for use.

func NewServiceWithContext

func NewServiceWithContext(ctx context.Context, opts ...Option) (context.Context, *Service)

NewServiceWithContext creates a new instance of Service with context, name and supplied options It is used together with the Init option to setup components of a service that is not yet running.

func (*Service) AddCleanupMethod

func (s *Service) AddCleanupMethod(f func(ctx context.Context))

AddCleanupMethod Adds user defined functions to be run just before completely stopping the service. These are responsible for properly and gracefully stopping active components.

func (*Service) AddHealthCheck

func (s *Service) AddHealthCheck(checker Checker)

AddHealthCheck Adds health checks that are run periodically to ascertain the system is ok The arguments are implementations of the checker interface and should work with just about any system that is given to them.

func (*Service) AddPreStartMethod

func (s *Service) AddPreStartMethod(f func(ctx context.Context, s *Service))

AddPreStartMethod Adds user defined functions that can be run just before the service starts receiving requests but is fully initialized.

func (*Service) AddPublisherStartup

func (s *Service) AddPublisherStartup(f func(ctx context.Context, s *Service))

AddPublisherStartup Adds publisher initialization functions that run before subscribers.

func (*Service) AddStartupError

func (s *Service) AddStartupError(err error)

AddStartupError stores errors that occur during startup initialization.

func (*Service) AddSubscriberStartup

func (s *Service) AddSubscriberStartup(f func(ctx context.Context, s *Service))

AddSubscriberStartup Adds subscriber initialization functions that run after publishers.

func (*Service) CacheManager

func (s *Service) CacheManager() cache.Manager

CacheManager returns the service's cache manager.

func (*Service) Config

func (s *Service) Config() any

func (*Service) DatastoreManager

func (s *Service) DatastoreManager() datastore.Manager

DatastoreManager returns the service's datastore manager.

func (*Service) Environment

func (s *Service) Environment() string

Environment gets the runtime environment of the service.

func (*Service) EventsManager

func (s *Service) EventsManager() events.Manager

func (*Service) GetRawCache

func (s *Service) GetRawCache(name string) (cache.RawCache, bool)

GetRawCache is a convenience method to get a raw cache by name from the service.

func (*Service) GetStartupErrors

func (s *Service) GetStartupErrors() []error

GetStartupErrors returns all errors that occurred during startup.

func (*Service) H

func (s *Service) H() http.Handler

func (*Service) HTTPClientManager

func (s *Service) HTTPClientManager() client.Manager

HTTPClientManager obtains an instrumented http client for making appropriate calls downstream.

func (*Service) HandleHealth

func (s *Service) HandleHealth(w http.ResponseWriter, _ *http.Request)

HandleHealth returns 200 with a JSON health report if all checks pass, 500 otherwise.

func (*Service) HandleHealthByDefault

func (s *Service) HandleHealthByDefault(w http.ResponseWriter, r *http.Request)

HandleHealthByDefault returns the health report at root, 404 for other paths.

func (*Service) HealthCheckers

func (s *Service) HealthCheckers() []Checker

func (*Service) Init

func (s *Service) Init(ctx context.Context, opts ...Option)

Init evaluates the options provided as arguments and supplies them to the service object. If called after initial startup, it will execute any new startup methods immediately.

func (*Service) LocalizationManager

func (s *Service) LocalizationManager() localization.Manager

func (*Service) Log

func (s *Service) Log(ctx context.Context) *util.LogEntry

func (*Service) Name

func (s *Service) Name() string

Name gets the name of the service. Its the first argument used when NewService is called.

func (*Service) OpenAPIRegistry

func (s *Service) OpenAPIRegistry() *openapi.Registry

func (*Service) QueueManager

func (s *Service) QueueManager() queue.Manager

func (*Service) Run

func (s *Service) Run(ctx context.Context, address string) error

Run keeps the service useful by handling incoming requests.

func (*Service) SLog

func (s *Service) SLog(ctx context.Context) *slog.Logger

func (*Service) SecurityManager

func (s *Service) SecurityManager() security.Manager

func (*Service) SetShutdownTimeout added in v2.0.2

func (s *Service) SetShutdownTimeout(timeout time.Duration)

SetShutdownTimeout sets the overall shutdown timeout for the service. If not set, defaults to HTTP server shutdown timeout from config.

func (*Service) Stop

func (s *Service) Stop(ctx context.Context)

Stop Used to gracefully run clean up methods ensuring all requests that were being handled are completed well without interuptions.

func (*Service) TLSEnabled

func (s *Service) TLSEnabled() bool

func (*Service) TelemetryManager

func (s *Service) TelemetryManager() telemetry.Manager

func (*Service) TenancyProvider

func (s *Service) TenancyProvider() tenancy.Provider

TenancyProvider returns the tenancy provider wired for the default pool. Used by tests and diagnostics. May be nil when tenancy has been explicitly disabled via WithTenancyProvider(nil).

func (*Service) Version

func (s *Service) Version() string

Version gets the release version of the service.

func (*Service) WorkManager

func (s *Service) WorkManager() workerpool.Manager

Directories

Path Synopsis
cmd
frame command
dialect
Package dialect defines the driver abstraction frame uses to talk to a database.
Package dialect defines the driver abstraction frame uses to talk to a database.
dialect/postgres
Package postgres provides the Postgres concrete DialectAdapter.
Package postgres provides the Postgres concrete DialectAdapter.
examples
datastore-basic command
http-basic command
queue-basic command
rlstest
Package rlstest provides a test-only tenancy.Provider wrapper that drops connections to an unprivileged role so Postgres FORCE ROW LEVEL SECURITY is actually enforced.
Package rlstest provides a test-only tenancy.Provider wrapper that drops connections to an unprivileged role so Postgres FORCE ROW LEVEL SECURITY is actually enforced.
Package ratelimiter provides admission-control primitives for protecting services from overload.
Package ratelimiter provides admission-control primitives for protecting services from overload.
authorizer
Package authorizer provides an Ory Keto adapter implementation for the security.Authorizer interface.
Package authorizer provides an Ory Keto adapter implementation for the security.Authorizer interface.
Package tenancy provides the storage-layer view of a principal's tenancy (Claims), the Provider abstraction for enforcement, and helpers to bind tenancy to a request context.
Package tenancy provides the storage-layer view of a principal's tenancy (Claims), the Provider abstraction for enforcement, and helpers to bind tenancy to a request context.
postgres
Package postgres provides the Postgres concrete tenancy.Provider.
Package postgres provides the Postgres concrete tenancy.Provider.
tools

Jump to

Keyboard shortcuts

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