| layout | page |
|---|---|
| title | Getting Started |
| permalink | /getting-started/ |
Get up and running with the Forge framework in just a few minutes.
go mod init my-service
go get github.com/datariot/forgeCreate a simple service with health checks and graceful shutdown:
package main
import (
"context"
"log"
"github.com/datariot/forge/config"
"github.com/datariot/forge/framework"
"github.com/datariot/forge/health"
)
// UserService implements the Component interface
type UserService struct {
config *config.BaseConfig
}
func (s *UserService) Start(ctx context.Context) error {
log.Printf("UserService started")
return nil
}
func (s *UserService) Stop(ctx context.Context) error {
log.Printf("UserService stopping gracefully")
return nil
}
func (s *UserService) HealthChecks() []health.Check {
return []health.Check{
health.NewAlwaysHealthyCheck("user-service"),
}
}
func main() {
// Load configuration
cfg := config.DefaultBaseConfig()
cfg.ServiceName = "user-service"
cfg.AppEnv = "development"
// Validate configuration
if err := cfg.Validate(); err != nil {
log.Fatalf("Configuration validation failed: %v", err)
}
// Create application
app, err := framework.New(
framework.WithConfig(&cfg),
framework.WithVersion("1.0.0"),
framework.WithComponent(&UserService{config: &cfg}),
framework.WithHealthContributor(&UserService{config: &cfg}),
)
if err != nil {
log.Fatalf("Failed to create application: %v", err)
}
// Run the service
log.Printf("Starting %s...", cfg.ServiceName)
if err := app.Run(context.Background()); err != nil {
log.Fatalf("Application failed: %v", err)
}
}go run main.goYour service will start with:
- gRPC server on
:8080 - HTTP health endpoints on
:8081http://localhost:8081/health- Overall healthhttp://localhost:8081/health/ready- Readiness probehttp://localhost:8081/health/live- Liveness probehttp://localhost:8081/metrics- Prometheus metrics
Add PostgreSQL with automatic health checks:
import (
"github.com/datariot/forge/bundles/postgresql"
)
func main() {
// Configure database
dbConfig := postgresql.Config{
DatabaseURL: "postgres://user:pass@localhost:5432/mydb?sslmode=require",
MaxOpenConns: 25,
MaxIdleConns: 10,
ConnMaxLifetime: 30 * time.Minute,
}
pgBundle := postgresql.NewBundle(dbConfig)
app, err := framework.New(
framework.WithConfig(&cfg),
framework.WithBundle(pgBundle), // Add database bundle
framework.WithComponent(service),
)
}Add Redis for caching and messaging:
import (
"github.com/datariot/forge/bundles/redis"
)
func main() {
// Configure Redis
redisConfig := redis.Config{
RedisURL: "redis://localhost:6379/0",
PoolSize: 10,
MinIdleConns: 2,
}
redisBundle := redis.NewBundle(redisConfig)
app, err := framework.New(
framework.WithConfig(&cfg),
framework.WithBundle(redisBundle), // Add caching bundle
framework.WithComponent(service),
)
// Use Redis in your service
cache := redisBundle.Cache()
cache.Set(ctx, "user:123", userData, 1*time.Hour)
}Secure service-to-service communication with JWT:
import (
"github.com/datariot/forge/bundles/jwt"
)
func main() {
// Configure JWT authentication
jwtConfig := jwt.Config{
SecretKey: []byte("your-32-plus-character-secret-key"),
Issuer: "auth-service",
Audience: "my-services",
ServiceName: cfg.ServiceName,
}
jwtBundle := jwt.NewBundle(jwtConfig)
app, err := framework.New(
framework.WithConfig(&cfg),
framework.WithBundle(jwtBundle), // Add authentication
framework.WithUnaryInterceptor(jwtBundle.UnaryServerInterceptor()),
framework.WithComponent(service),
)
}Configure your service using environment variables:
# Service configuration
export SERVICE_NAME="user-service"
export APP_ENV="production"
export GRPC_ADDR=":8080"
export HTTP_ADDR=":8081"
export LOG_LEVEL="info"
# Database configuration
export DATABASE_URL="postgres://user:pass@db-host:5432/mydb?sslmode=require"
# Redis configuration
export REDIS_URL="redis://redis-host:6379/0"
# JWT authentication
export JWT_SECRET="your-production-secret-key-32-characters-minimum"
export JWT_ISSUER="auth-service"
export JWT_AUDIENCE="production-services"
# Run your service
go run main.go- Explore Bundles - Learn about available integrations
- View Examples - See complete working examples
- API Reference - Detailed API documentation
Components are your business logic that implement the Component interface:
type Component interface {
Start(ctx context.Context) error
Stop(ctx context.Context) error
}Bundles are pre-built integrations that add functionality to your application:
type Bundle interface {
Name() string
Initialize(app *App) error
}Implement health checks for monitoring and alerting:
type HealthContributor interface {
HealthChecks() []health.Check
}Forge handles sophisticated startup and shutdown:
- Initialize configuration and logging
- Initialize bundles (PostgreSQL, Redis, etc.)
- Start gRPC and HTTP servers
- Start your components
- Mark service as ready
- Handle graceful shutdown in reverse order