Documentation Index Fetch the complete documentation index at: https://mintlify.com/platforma-dev/platforma/llms.txt
Use this file to discover all available pages before exploring further.
The Application type manages the complete lifecycle of your application, from startup tasks through graceful shutdown.
Application Type
Defined in application/application.go:36, the Application coordinates:
Startup tasks - Run sequentially before services start
Services - Long-running processes (HTTP servers, queue processors)
Databases - Database connections with migration support
Health checks - Service health monitoring
type Application struct {
startupTasks [] startupTask
services map [ string ] Runner
healthcheckers map [ string ] Healthchecker
databases map [ string ] * database . Database
health * Health
}
Basic Setup
Create and run an application:
package main
import (
" context "
" github.com/platforma-dev/platforma/application "
)
func main () {
ctx := context . Background ()
// Create new application
app := application . New ()
// Register components...
// Run with CLI argument parsing
if err := app . Run ( ctx ); err != nil {
log . ErrorContext ( ctx , "app failed" , "error" , err )
}
}
app.Run(ctx) automatically parses command-line arguments. Run with run command to start services or migrate to run database migrations.
Registration Methods
RegisterDatabase
Register a database connection defined in application/application.go:68:
db := database . New ( connString )
app . RegisterDatabase ( "main" , db )
Databases are automatically migrated during the migrate command.
RegisterDomain
Register a domain and its repository from application/application.go:90:
app . RegisterDomain (
"auth" , // domain name
"main" , // database name
authDomain , // domain implementing Domain interface
)
This automatically registers the domain’s repository with the specified database for migration tracking.
RegisterService
Register a long-running service from application/application.go:78:
app . RegisterService ( "api" , httpServer )
app . RegisterService ( "queue_processor" , processor )
app . RegisterService ( "scheduler" , scheduler )
Services must implement the Runner interface:
type Runner interface {
Run ( context . Context ) error
}
Services implementing Healthchecker are automatically registered for health monitoring.
RegisterRepository
Directly register a repository from application/application.go:73:
app . RegisterRepository ( "main" , "users_repo" , userRepository )
Usually not needed - RegisterDomain() handles this automatically.
Startup Tasks
Run initialization logic before services start using application/application.go:58:
app . OnStartFunc (
func ( ctx context . Context ) error {
log . InfoContext ( ctx , "seeding database" )
return seedDatabase ( ctx )
},
application . StartupTaskConfig {
Name : "seed_database" ,
AbortOnError : true , // Stop app if this fails
},
)
Startup Task Configuration
From application/startuptask.go:21:
type StartupTaskConfig struct {
Name string // Task name for logging
AbortOnError bool // Whether to stop app on failure
}
Startup tasks run sequentially in registration order. If AbortOnError is true, a failure prevents service startup.
Complete Lifecycle Example
From demo-app/cmd/api/main.go, showing the full application setup:
package main
import (
" context "
" net/http "
" time "
" github.com/platforma-dev/platforma/application "
" github.com/platforma-dev/platforma/httpserver "
" github.com/platforma-dev/platforma/log "
)
func main () {
ctx := context . Background ()
// Initialize application
app := application . New ()
// Create HTTP server
api := httpserver . New ( "8080" , 3 * time . Second )
// Add endpoints
api . HandleFunc ( "/ping" , func ( w http . ResponseWriter , r * http . Request ) {
w . Write ([] byte ( "pong" ))
})
// Add middleware
api . Use ( log . NewTraceIDMiddleware ( nil , "" ))
// Create handler group
subApiGroup := httpserver . NewHandlerGroup ()
subApiGroup . HandleFunc ( "/clock" , func ( w http . ResponseWriter , r * http . Request ) {
w . Write ([] byte ( time . Now (). String ()))
})
// Mount handler group
api . HandleGroup ( "/subApi" , subApiGroup )
// Register HTTP server as service
app . RegisterService ( "api" , api )
// Run application
if err := app . Run ( ctx ); err != nil {
log . ErrorContext ( ctx , "app finished with error" , "error" , err )
}
}
CLI Commands
The Run method from application/application.go:180 supports these commands:
Starts all registered services:
Executes startup tasks sequentially
Starts all services concurrently
Waits for interrupt signal (Ctrl+C)
Performs graceful shutdown
Runs database migrations:
Executes migrations for all registered databases
Applies pending migrations in order
Does not start services
Service Lifecycle
When you run ./myapp run, the application:
Runs startup tasks (application/application.go:129) - Sequential execution
Starts services (application/application.go:146) - Concurrent goroutines with panic recovery
Updates health status (application/application.go:160) - Tracks service state
Waits for shutdown (application/application.go:124) - Listens for OS signals
Graceful shutdown - Services receive context cancellation
// Service execution from application.go:146-168
for serviceName , service := range a . services {
wg . Add ( 1 )
serviceCtx := context . WithValue ( ctx , log . ServiceNameKey , serviceName )
go func () {
defer wg . Done ()
defer func () {
if r := recover (); r != nil {
log . ErrorContext ( serviceCtx , "service panicked" ,
"panic" , r )
}
}()
log . InfoContext ( ctx , "starting service" , "service" , serviceName )
a . health . StartService ( serviceName )
err := service . Run ( serviceCtx )
if err != nil {
a . health . FailService ( serviceName , err )
log . ErrorContext ( ctx , "error in service" , "error" , err )
}
}()
}
Services receive a context that’s cancelled on shutdown. Implement graceful shutdown by monitoring ctx.Done().
Graceful Shutdown
The application handles SIGINT and SIGKILL signals (application/application.go:124):
ctx , cancel := signal . NotifyContext ( ctx , os . Interrupt , os . Kill )
defer cancel ()
Services should respect context cancellation:
func ( s * MyService ) Run ( ctx context . Context ) error {
for {
select {
case <- ctx . Done ():
log . InfoContext ( ctx , "shutting down gracefully" )
return nil
case work := <- s . workChan :
s . process ( work )
}
}
}
The HTTPServer automatically implements graceful shutdown with a configurable timeout.
Error Handling
Specialized errors from the application package:
// Startup task failure (application/startuptask.go:6)
type ErrStartupTaskFailed struct {
err error
}
// Database migration failure (application/application.go:21)
type ErrDatabaseMigrationFailed struct {
err error
}
// Unknown CLI command (application/application.go:18)
var ErrUnknownCommand = errors . New ( "unknown command" )
Health Monitoring
Access health status via application/application.go:50:
health := app . Health ( ctx )
// Returns *Health with service status and health check data
Services implementing Healthchecker provide custom health data:
type Healthchecker interface {
Healthcheck ( context . Context ) any
}
Next Steps
Domains Learn how to create and structure domains
HTTP Routing Set up HTTP servers and routes
Database Configure databases and migrations