Documentation
¶
Overview ¶
Package framework provides the core application lifecycle management for Forge microservices.
The framework package implements Clean Architecture principles with a component-based design that enables building production-ready microservices with built-in observability, health checks, graceful shutdown, and lifecycle management.
Basic Usage ¶
Create a service by implementing the Component interface and using the App builder:
cfg := config.DefaultBaseConfig()
cfg.ServiceName = "my-service"
myComponent := &MyComponent{}
app, err := framework.New(
framework.WithConfig(&cfg),
framework.WithVersion("1.0.0"),
framework.WithComponent(myComponent),
)
if err != nil {
log.Fatal(err)
}
if err := app.Run(context.Background()); err != nil {
log.Fatal(err)
}
Architecture ¶
The framework follows Clean Architecture with these key concepts:
- Components: Your business logic implementing Component interface
- Bundles: Pre-built integrations (PostgreSQL, Redis, etc.)
- App: Main application orchestrating lifecycle and dependencies
- Health: Comprehensive health check system with liveness/readiness
- Observability: Built-in OpenTelemetry tracing and metrics
Lifecycle Management ¶
The App handles sophisticated startup and shutdown orchestration:
- Initialize observability (tracing, metrics)
- Initialize bundles in registration order
- Execute startup hooks
- Start gRPC and HTTP servers
- Start components in registration order
- Mark service as ready
Shutdown happens in reverse order with proper timeout handling and graceful termination.
Index ¶
- func NewHealthLogger(logging *LoggingManager) *healthLoggerAdapter
- type App
- func (a *App) Config() *config.BaseConfig
- func (a *App) HealthRegistry() *forgeHealth.Registry
- func (a *App) IsRunning() bool
- func (a *App) IsStopping() bool
- func (a *App) Logger() *LoggingManager
- func (a *App) Run(ctx context.Context) error
- func (a *App) Start(ctx context.Context) error
- func (a *App) Stop(ctx context.Context) error
- func (a *App) Uptime() time.Duration
- type AppOption
- func WithBundle(bundle Bundle) AppOption
- func WithComponent(component Component) AppOption
- func WithConfig(config *config.BaseConfig) AppOption
- func WithGRPCRegistrar(registrar Registrar) AppOption
- func WithHealthContributor(contributor HealthContributor) AppOption
- func WithShutdownHook(hook ShutdownHook) AppOption
- func WithStartupHook(hook StartupHook) AppOption
- func WithStreamInterceptor(interceptor grpc.StreamServerInterceptor) AppOption
- func WithUnaryInterceptor(interceptor grpc.UnaryServerInterceptor) AppOption
- func WithVersion(version string) AppOption
- type Bundle
- type Component
- type HTTPServerBuilder
- type HTTPServerConfig
- type HealthContributor
- type LoggingManager
- type ObservabilityConfig
- type ObservabilityManager
- type OrchestrationHook
- type Registrar
- type ShutdownHook
- type ShutdownHookFunc
- type ShutdownOrchestrator
- type StartupHook
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewHealthLogger ¶
func NewHealthLogger(logging *LoggingManager) *healthLoggerAdapter
NewHealthLogger creates a logger adapter for the health system.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App represents the main service application with lifecycle management. App orchestrates the entire application lifecycle including initialization, startup, runtime, and graceful shutdown of all registered components and services.
The App follows a sophisticated startup sequence:
- Configuration validation
- Logging and observability initialization
- Bundle initialization (in registration order)
- Startup hook execution
- gRPC and HTTP server startup
- Component startup (in registration order)
- Health check registration and readiness marking
Shutdown happens in reverse order with proper timeout handling. The App ensures all resources are cleaned up gracefully on termination.
func (*App) Config ¶
func (a *App) Config() *config.BaseConfig
Config returns the application configuration.
func (*App) HealthRegistry ¶
func (a *App) HealthRegistry() *forgeHealth.Registry
HealthRegistry returns the health registry.
func (*App) IsStopping ¶
IsStopping returns true if the application is in the process of stopping.
type AppOption ¶
AppOption configures the App during creation.
func WithBundle ¶
WithBundle adds a bundle to the application.
func WithComponent ¶
WithComponent adds a component to be managed by the app.
func WithConfig ¶
func WithConfig(config *config.BaseConfig) AppOption
WithConfig sets the base configuration.
func WithGRPCRegistrar ¶
WithGRPCRegistrar adds a gRPC service registrar.
func WithHealthContributor ¶
func WithHealthContributor(contributor HealthContributor) AppOption
WithHealthContributor adds health checks from a contributor.
func WithShutdownHook ¶
func WithShutdownHook(hook ShutdownHook) AppOption
WithShutdownHook adds a shutdown hook.
func WithStartupHook ¶
func WithStartupHook(hook StartupHook) AppOption
WithStartupHook adds a startup hook.
func WithStreamInterceptor ¶
func WithStreamInterceptor(interceptor grpc.StreamServerInterceptor) AppOption
WithStreamInterceptor adds a gRPC stream server interceptor.
func WithUnaryInterceptor ¶
func WithUnaryInterceptor(interceptor grpc.UnaryServerInterceptor) AppOption
WithUnaryInterceptor adds a gRPC unary server interceptor.
type Bundle ¶
type Bundle interface {
// Name returns a unique identifier for this bundle.
Name() string
// Initialize sets up the bundle's functionality within the application.
// This method is called during application startup before components are started.
Initialize(app *App) error
// Stop gracefully shuts down the bundle and cleans up resources.
// This method is called during application shutdown in reverse initialization order.
// Bundles should respect the context deadline for graceful termination.
Stop(ctx context.Context) error
}
Bundle represents a reusable collection of functionality that can be added to an app. Bundles encapsulate common integrations like database connections, message queues, monitoring, etc. They are initialized in registration order during startup and stopped in reverse order during shutdown.
Example bundle for PostgreSQL integration:
type PostgreSQLBundle struct {
config *DatabaseConfig
db *sql.DB
}
func (b *PostgreSQLBundle) Name() string {
return "postgresql"
}
func (b *PostgreSQLBundle) Initialize(app *App) error {
db, err := sql.Open("postgres", b.config.URL)
if err != nil {
return err
}
b.db = db
return nil
}
func (b *PostgreSQLBundle) Stop(ctx context.Context) error {
if b.db != nil {
return b.db.Close()
}
return nil
}
type Component ¶
type Component interface {
// Start initializes the component and starts any background processes.
// This method is called during application startup after all bundles
// have been initialized and servers have been started.
Start(ctx context.Context) error
// Stop gracefully shuts down the component and cleans up resources.
// This method is called during application shutdown with a timeout context.
// Components should respect the context deadline for graceful termination.
Stop(ctx context.Context) error
}
Component represents a service component that can be started and stopped. Components are the primary way to integrate your business logic with the Forge framework.
Components are started in registration order during application startup and stopped in reverse order during graceful shutdown. Each component should handle its own resource management and cleanup.
Example implementation:
type UserService struct {
db *sql.DB
}
func (s *UserService) Start(ctx context.Context) error {
// Initialize connections, start background workers, etc.
return s.db.PingContext(ctx)
}
func (s *UserService) Stop(ctx context.Context) error {
// Clean up resources, stop workers, close connections
return s.db.Close()
}
type HTTPServerBuilder ¶
type HTTPServerBuilder struct {
// contains filtered or unexported fields
}
HTTPServerBuilder builds an enhanced HTTP server with configurable endpoints.
func NewHTTPServerBuilder ¶
func NewHTTPServerBuilder(app *App, config HTTPServerConfig) *HTTPServerBuilder
NewHTTPServerBuilder creates a new HTTP server builder.
func (*HTTPServerBuilder) Build ¶
func (b *HTTPServerBuilder) Build() *http.Server
Build constructs the HTTP server with all configured endpoints and middleware.
type HTTPServerConfig ¶
type HTTPServerConfig struct {
// CORS configuration
EnableCORS bool `yaml:"enable_cors" env:"ENABLE_CORS"`
CORSOrigins []string `yaml:"cors_origins" env:"CORS_ORIGINS"`
CORSMethods []string `yaml:"cors_methods" env:"CORS_METHODS"`
CORSHeaders []string `yaml:"cors_headers" env:"CORS_HEADERS"`
CORSCredentials bool `yaml:"cors_credentials" env:"CORS_CREDENTIALS"`
// Endpoint configuration
EnableMetrics bool `yaml:"enable_metrics" env:"ENABLE_METRICS"`
MetricsPath string `yaml:"metrics_path" env:"METRICS_PATH"`
HealthPathPrefix string `yaml:"health_path_prefix" env:"HEALTH_PATH_PREFIX"`
// Request logging
EnableRequestLogging bool `yaml:"enable_request_logging" env:"ENABLE_REQUEST_LOGGING"`
LogRequestBody bool `yaml:"log_request_body" env:"LOG_REQUEST_BODY"`
LogResponseBody bool `yaml:"log_response_body" env:"LOG_RESPONSE_BODY"`
}
HTTPServerConfig contains configuration for the HTTP server endpoints.
func DefaultHTTPServerConfig ¶
func DefaultHTTPServerConfig() HTTPServerConfig
DefaultHTTPServerConfig returns HTTP server configuration with sensible defaults.
func (*HTTPServerConfig) Validate ¶
func (c *HTTPServerConfig) Validate() error
Validate performs comprehensive validation on HTTP server configuration.
type HealthContributor ¶
type HealthContributor interface {
// HealthChecks returns a slice of health checks that this component provides.
// These checks will be automatically registered during application startup.
HealthChecks() []forgeHealth.Check
}
HealthContributor represents a service that contributes health checks. Components implementing this interface can provide health checks that will be automatically registered with the health registry.
Example:
func (s *UserService) HealthChecks() []health.Check {
return []forgeHealth.Check{
forgeHealth.NewBasicCheck(
forgeHealth.DefaultCheckConfig("database"),
func(ctx context.Context) error {
return s.db.PingContext(ctx)
},
func(ctx context.Context) error {
return s.db.PingContext(ctx)
},
),
}
}
type LoggingManager ¶
type LoggingManager struct {
// contains filtered or unexported fields
}
LoggingManager manages logging configuration and provides logger instances.
func NewLoggingManager ¶
func NewLoggingManager(config *config.BaseConfig) *LoggingManager
NewLoggingManager creates a new logging manager with the given configuration.
func (*LoggingManager) Initialize ¶
func (lm *LoggingManager) Initialize() error
Initialize sets up the logging configuration.
func (*LoggingManager) Logger ¶
func (lm *LoggingManager) Logger() *zerolog.Logger
Logger returns the base logger instance.
func (*LoggingManager) WithContext ¶
func (lm *LoggingManager) WithContext(fields map[string]interface{}) zerolog.Logger
WithContext creates a logger with additional context fields.
func (*LoggingManager) WithService ¶
func (lm *LoggingManager) WithService(service, component string) zerolog.Logger
WithService creates a logger with service and component context.
type ObservabilityConfig ¶
type ObservabilityConfig struct {
ServiceName string
ServiceVersion string
Environment string
OTELEndpoint string
SampleRate float64
}
ObservabilityConfig contains configuration for observability (tracing, metrics).
func NewObservabilityConfig ¶
func NewObservabilityConfig(baseConfig *config.BaseConfig, version string) *ObservabilityConfig
NewObservabilityConfig creates a new observability config from base config.
type ObservabilityManager ¶
type ObservabilityManager struct {
// contains filtered or unexported fields
}
ObservabilityManager manages OpenTelemetry tracing and metrics.
func NewObservabilityManager ¶
func NewObservabilityManager(config *ObservabilityConfig) *ObservabilityManager
NewObservabilityManager creates a new observability manager.
func (*ObservabilityManager) GetMeter ¶
func (om *ObservabilityManager) GetMeter(name string) otelmetric.Meter
GetMeter returns a meter for the given name.
func (*ObservabilityManager) GetTracer ¶
func (om *ObservabilityManager) GetTracer(name string) oteltrace.Tracer
GetTracer returns a tracer for the given name.
func (*ObservabilityManager) Initialize ¶
func (om *ObservabilityManager) Initialize(ctx context.Context) error
Initialize sets up OpenTelemetry tracing and metrics.
type OrchestrationHook ¶
type OrchestrationHook struct {
Name string
Func ShutdownHookFunc
}
OrchestrationHook represents a named shutdown hook with a cleanup function.
func ComponentShutdownHook ¶
func ComponentShutdownHook(name string, component Component) OrchestrationHook
ComponentShutdownHook creates a shutdown hook for a Component.
type Registrar ¶
type Registrar interface {
// RegisterGRPC registers gRPC service handlers with the provided server.
// This method is called during application startup before the gRPC server starts.
RegisterGRPC(server *grpc.Server) error
}
Registrar represents a service that can register gRPC handlers. Components that expose gRPC services should implement this interface to register their handlers with the framework's gRPC server.
Example:
func (s *UserService) RegisterGRPC(server *grpc.Server) error {
userpb.RegisterUserServiceServer(server, s)
return nil
}
type ShutdownHook ¶
ShutdownHook is called during application shutdown. Use shutdown hooks for custom cleanup logic that needs to run before components are stopped. Hooks are executed in reverse registration order.
type ShutdownHookFunc ¶
ShutdownHookFunc is a function that performs cleanup during shutdown.
type ShutdownOrchestrator ¶
type ShutdownOrchestrator struct {
// contains filtered or unexported fields
}
ShutdownOrchestrator manages the graceful shutdown of service components.
func NewShutdownOrchestrator ¶
func NewShutdownOrchestrator(timeout time.Duration) *ShutdownOrchestrator
NewShutdownOrchestrator creates a new shutdown orchestrator with the given timeout.
func (*ShutdownOrchestrator) RegisterHook ¶
func (so *ShutdownOrchestrator) RegisterHook(name string, hookFunc ShutdownHookFunc)
RegisterHook adds a shutdown hook to be executed during shutdown. Hooks are executed in the order they were registered.
func (*ShutdownOrchestrator) RegisterHookWithTimeout ¶
func (so *ShutdownOrchestrator) RegisterHookWithTimeout(name string, timeout time.Duration, hookFunc ShutdownHookFunc)
RegisterHookWithTimeout adds a shutdown hook with a specific timeout.