Schema
YAML schema definitions and validation for deployment configurations
Overview
The schema package provides type definitions for YAML deployment configurations and embeds the JSON schema for validation. It defines the structure for all deployment-related configuration including services, routers, middleware, and deployment topology.
Import Path
import "github.com/primadi/lokstra/core/deploy/schema"
Core Types
DeployConfig
Root configuration structure for YAML files.
Definition:
type DeployConfig struct {
Configs map[string]any
MiddlewareDefinitions map[string]*MiddlewareDef
ServiceDefinitions map[string]*ServiceDef
RouterDefinitions map[string]*RouterDef // Renamed from "Routers"
ExternalServiceDefinitions map[string]*RemoteServiceSimple
Deployments map[string]*DeploymentDefMap
// RouterOverrides removed - overrides are now inline in RouterDef
}
YAML Example:
configs:
app.name: "MyApp"
app.version: "1.0.0"
service-definitions:
user-service:
type: user-service-factory
router-definitions:
user-router:
convention: rest
resource: user
deployments:
production:
servers:
api-server:
base-url: https://api.example.com
Service Definitions
ServiceDef
Defines a service instance.
Definition:
type ServiceDef struct {
Name string
Type string // Factory type
DependsOn []string // Dependencies
Config map[string]any // Optional config
}
YAML Example:
service-definitions:
user-service:
type: user-service-factory
depends-on:
- db-service
- cache-service
config:
max_connections: 100
timeout: 30s
Dependency Syntax:
# Simple dependency (uses service name as key)
depends-on:
- db-service
# Explicit mapping (custom key)
depends-on:
- userRepo:user-repository
- paymentSvc:payment-service
RemoteServiceSimple
Defines an external service (outside this deployment).
Definition:
type RemoteServiceSimple struct {
URL string
Type string // Factory type (auto-creates wrapper)
Resource string // Resource name (singular)
ResourcePlural string // Resource name (plural)
Convention string // Convention type (rest, rpc, graphql)
// Inline overrides (no more references)
PathPrefix string
PathRewrites []PathRewriteDef // Regex-based path rewrite rules
Middlewares []string
Hidden []string
Custom []RouteDef
Config map[string]any // Additional factory config
}
YAML Example:
external-service-definitions:
payment-service:
url: https://payment-api.example.com
type: payment-service-factory
resource: payment
resource-plural: payments
convention: rest
path-prefix: /api/v1
path-rewrites:
- pattern: "^/api/v1/(.*)$"
replacement: "/v2/$1"
middlewares:
- auth
- rate-limiter
config:
api_key: "${PAYMENT_API_KEY}"
timeout: 10s
Use Cases:
- Third-party APIs (Stripe, SendGrid, etc.)
- Microservices in other deployments
- External REST/RPC services
- Legacy system integration
Router Definitions
RouterDef
Defines a router auto-generated from a service, or middleware overrides for manual routers.
Router Naming Convention:
- Router name determines the service name using pattern
{service-name}-router - Example:
user-service-routerβ service isuser-service
Manual routers (registered via RegisterRouter()) can also use router-definitions for:
- Path prefix overrides
- Middleware injection
- Route-level customization
Definition:
type RouterDef struct {
// Service name is derived from router name pattern: "{service-name}-router"
// Example: "user-service-router" β service is "user-service"
Convention string // Convention type (rest, rpc, graphql) - for auto-generated only
Resource string // Singular form (e.g., "user") - for auto-generated only
ResourcePlural string // Plural form (e.g., "users") - for auto-generated only
// Inline overrides (works for both auto-generated AND manual routers)
PathPrefix string // Path prefix override
PathRewrites []PathRewriteDef // Regex-based path rewrite rules
Middlewares []string // Router-level middleware names
Hidden []string // Methods to hide (auto-generated only)
Custom []RouteDef // Custom route definitions
}
type PathRewriteDef struct {
Pattern string // Regex pattern to match (e.g., "^/api/v1/(.*)$")
Replacement string // Replacement string (e.g., "/api/v2/$1")
}
YAML Example (Auto-Generated Router):
router-definitions:
user-service-router: # Service derived: "user-service"
convention: rest
resource: user
resource-plural: users
# Inline overrides
path-prefix: /api/v1
middlewares:
- auth
- logger
hidden:
- InternalHelper
custom:
- name: Login
method: POST
path: /auth/login
middlewares:
- rate-limiter
YAML Example (Manual Router Overrides):
# Code: Manual router registration
# r := router.New("")
# r.GET("/dashboard", handler.ShowDashboard, route.WithNameOption("showDashboard"))
# r.GET("/users", handler.ListUsers) # Auto-name: "GET_/users"
# lokstra_registry.RegisterRouter("admin-router", r)
router-definitions:
admin-router: # Manual router (already registered in code)
# Supported overrides for manual routers
path-prefix: /api/v1/admin # Change path prefix
middlewares:
- admin-auth
- audit-log
# Route-level overrides (by route name)
custom:
- name: showDashboard # Update named route
method: POST # Change method from GET to POST
path: /admin/main # Change path
middlewares:
- extra-logging
- name: GET_/users # Update auto-named route
middlewares:
- rate-limiter # Just add middlewares
# Note: convention, resource, hidden are ignored for manual routers
Router Naming Convention:
- Format:
{service-name}-router - Service name: Remove
-routersuffix - Examples:
user-service-routerβuser-serviceorder-service-routerβorder-servicepayment-routerβpaymentadmin-routerβ manual router (no auto-generation)
Use Cases for Manual Router Overrides:
- Apply environment-specific middlewares (auth only in prod)
- Add monitoring/logging per deployment
- Inject rate limiting from YAML configuration
- Change path prefix per environment (API versioning)
- Rewrite paths using regex patterns (flexible transformations)
- Update specific route methods or paths per environment
- Add route-specific middlewares without changing code
- Keep router logic in code, configuration in YAML
Path Rewrites
Path rewrites allow regex-based transformation of route paths at build time. This is more flexible than path-prefix for complex URL transformations.
When to use:
path-prefix: Simple prefix addition (e.g., add/api/v1to all routes)path-rewrites: Complex transformations (e.g., change/api/v1/to/api/v2/, add tenant IDs, etc.)
Example: API Versioning
router-definitions:
user-router:
path-rewrites:
- pattern: "^/api/v1/(.*)$"
replacement: "/api/v2/$1"
Result:
Code: r.GET("/api/v1/users", ...)
After rewrite: GET /api/v2/users
Internal name: GET_/api/v1/users (unchanged)
Example: Multi-Tenant Paths
router-definitions:
tenant-router:
path-rewrites:
- pattern: "^/(.*)$"
replacement: "/tenant/${TENANT_ID}/$1"
Result:
Code: r.GET("/users", ...)
After rewrite: GET /tenant/acme-corp/users
Example: Multiple Rules
router-definitions:
api-router:
path-rewrites:
- pattern: "^/v1/(.*)$"
replacement: "/api/v2/$1"
- pattern: "^/legacy/(.*)$"
replacement: "/api/v2/compat/$1"
Rules:
- Applied in order (first match wins)
- Uses Goβs
regexppackage - Supports capture groups:
$1,$2, etc. - Applied at router build time (zero runtime overhead)
- Route names unchanged (only HTTP paths affected)
Combining with path-prefix:
router-definitions:
api-router:
path-prefix: /v2 # Applied first
path-rewrites: # Applied after prefix
- pattern: "^/v2/old/(.*)$"
replacement: "/v2/new/$1"
RouteDef
Defines a single route override.
Definition:
type RouteDef struct {
Name string // Route name (manual or auto-generated)
Method string // HTTP method override
Path string // Path override
Middlewares []string // Route-level middleware names
}
YAML Example:
custom:
- name: Login
method: POST
path: /auth/login
middlewares: # Route-level middlewares
- rate-limiter-strict
- name: Logout
method: POST
path: /auth/logout
- name: AdminReset
method: POST
path: /admin/reset
middlewares:
- admin-auth
- audit-log
Middleware Definitions
MiddlewareDef
Defines a middleware instance.
Definition:
type MiddlewareDef struct {
Name string
Type string // Factory type
Config map[string]any // Optional config
}
YAML Example:
middleware-definitions:
logger-debug:
type: logger
config:
level: DEBUG
colorize: true
cors-dev:
type: cors
config:
allow_origin: "*"
allow_methods: "*"
allow_headers: "*"
rate-limiter-strict:
type: rate-limiter
config:
requests_per_minute: 10
burst: 5
Configuration
ConfigDef
Defines a configuration value.
Definition:
type ConfigDef struct {
Name string
Value any // Can be string or ${...} reference
}
YAML Example:
configs:
app.name: "MyApp"
app.port: 8080
app.env: "${APP_ENV:development}"
db.dsn: "${DATABASE_URL}"
log.level: "INFO"
Deployment Topology
DeploymentDefMap
Deployment using map structure.
Definition:
type DeploymentDefMap struct {
ConfigOverrides map[string]any
Servers map[string]*ServerDefMap
}
YAML Example:
deployments:
production:
config-overrides:
log.level: INFO
db.pool_size: 100
servers:
api-server-1:
# ...
api-server-2:
# ...
ServerDefMap
Server using map structure.
Definition:
type ServerDefMap struct {
BaseURL string
Apps []*AppDefMap
// Helper fields (shorthand for single app)
HelperAddr string
HelperRouters []string
HelperPublishedServices []string
}
YAML Example (Full):
servers:
api-server:
base-url: https://api.example.com
apps:
- addr: ":443"
routers:
- user-router
- order-router
- addr: ":8080"
routers:
- admin-router
YAML Example (Shorthand):
servers:
api-server:
base-url: https://api.example.com
# Shorthand for single app
addr: ":443"
routers:
- user-router
- order-router
AppDefMap
App using map structure.
Definition:
type AppDefMap struct {
Addr string
Routers []string
PublishedServices []string // Auto-generate routers for these services
}
YAML Example:
apps:
- addr: ":8080"
routers:
- user-router
- order-router
- addr: ":9090"
# Auto-generate routers from services
published-services:
- user-service
- order-service
Schema Validation
GetSchemaBytes
Returns the embedded JSON schema for validation.
Signature:
func GetSchemaBytes() []byte
Example:
schemaBytes := schema.GetSchemaBytes()
// Use with JSON schema validator
Complete Examples
Minimal Configuration
service-definitions:
user-service:
type: user-service-factory
router-definitions:
user-service-router: # Service derived: "user-service"
convention: rest
deployments:
production:
servers:
api-server:
base-url: https://api.example.com
addr: ":443"
routers:
- user-service-router
Full-Featured Configuration
# Configuration values
configs:
app.name: "MyApp"
app.version: "1.0.0"
app.env: "${APP_ENV:production}"
db.dsn: "${DATABASE_URL}"
db.pool_size: 100
# Middleware definitions
middleware-definitions:
logger:
type: logger
config:
level: INFO
auth:
type: jwt-auth
config:
secret: "${JWT_SECRET}"
rate-limiter:
type: rate-limiter
config:
requests_per_minute: 60
burst: 10
# Service definitions
service-definitions:
db-service:
type: postgres-factory
config:
dsn: "${@cfg:db.dsn}"
pool_size: "${@cfg:db.pool_size}"
cache-service:
type: redis-factory
config:
addr: "${REDIS_URL:localhost:6379}"
user-service:
type: user-service-factory
depends-on:
- db-service
- cache-service
config:
max_users: 10000
order-service:
type: order-service-factory
depends-on:
- db-service
- user-service
config:
max_orders: 50000
# Router definitions
router-definitions:
user-service-router: # Service derived: "user-service"
convention: rest
resource: user
resource-plural: users
# Inline overrides
path-prefix: /api/v1
middlewares:
- auth
- logger
hidden:
- InternalHelper
custom:
- name: Login
method: POST
path: /auth/login
middlewares:
- rate-limiter-strict
- name: Logout
method: POST
path: /auth/logout
order-service-router: # Service derived: "order-service"
convention: rest
resource: order
resource-plural: orders
# External services
external-service-definitions:
payment-service:
url: https://payment-api.example.com
type: payment-client-factory
resource: payment
resource-plural: payments
config:
api_key: "${PAYMENT_API_KEY}"
# Deployments
deployments:
production:
config-overrides:
log.level: INFO
db.pool_size: 100
servers:
api-server-1:
base-url: https://api-1.example.com
apps:
- addr: ":443"
routers:
- user-service-router
- order-service-router
api-server-2:
base-url: https://api-2.example.com
apps:
- addr: ":443"
routers:
- user-service-router
- order-service-router
Multi-Environment Configuration
# Base configuration (shared)
service-definitions:
user-service:
type: user-service-factory
router-definitions:
user-service-router:
convention: rest
# Development deployment
deployments:
development:
config-overrides:
log.level: DEBUG
db.pool_size: 10
servers:
dev-server:
base-url: http://localhost:8080
addr: ":8080"
routers:
- user-service-router
# Staging deployment
deployments:
staging:
config-overrides:
log.level: INFO
db.pool_size: 50
servers:
staging-server:
base-url: https://staging.example.com
addr: ":443"
routers:
- user-service-router
# Production deployment
deployments:
production:
config-overrides:
log.level: WARN
db.pool_size: 100
servers:
api-server-1:
base-url: https://api-1.example.com
addr: ":443"
routers:
- user-service-router
api-server-2:
base-url: https://api-2.example.com
addr: ":443"
routers:
- user-service-router
Microservices Architecture
# User service deployment
service-definitions:
user-service:
type: user-service-factory
deployments:
user-deployment:
servers:
user-server:
base-url: https://user-api.example.com
addr: ":443"
published-services:
- user-service
---
# Order service deployment (separate file)
service-definitions:
order-service:
type: order-service-factory
# External user service
external-service-definitions:
user-service:
url: https://user-api.example.com
type: user-service-factory
deployments:
order-deployment:
servers:
order-server:
base-url: https://order-api.example.com
addr: ":443"
published-services:
- order-service
Schema Validation Rules
Required Fields
ServiceDef:
- β
type- Service factory type must be specified - β
config- Optional - β
depends-on- Optional
RouterDef:
- β
service- REMOVED (derived from router name pattern) - β
convention- Optional (defaults to βrestβ) - β
resource- Optional (auto-detected from service name)
DeploymentDefMap:
- β
servers- At least one server required - β
config-overrides- Optional
ServerDefMap:
- β
base-url- Base URL required - β
appsor helper fields (addr+routers/published-services)
Field Types
String Fields:
type,name,service,convention,resource,url,addr,path-prefix
String Array Fields:
depends-on,middlewares,routers,hidden,published-services
Map Fields:
config,configs,config-overrides
Object Fields:
service-definitions,routers,router-overrides,external-service-definitions,deployments
Best Practices
1. Use Meaningful Names
# β
Good: Descriptive names
service-definitions:
user-management-service:
type: user-service-factory
product-catalog-service:
type: catalog-service-factory
# π« Avoid: Cryptic names
service-definitions:
svc1:
type: user-service-factory
svc2:
type: catalog-service-factory
2. Group Related Configurations
# β
Good: Logical grouping
configs:
# Database settings
db.host: "localhost"
db.port: 5432
db.name: "myapp"
# Cache settings
cache.host: "localhost"
cache.port: 6379
# App settings
app.name: "MyApp"
app.version: "1.0.0"
# π« Avoid: Random order
configs:
app.name: "MyApp"
db.host: "localhost"
cache.port: 6379
db.port: 5432
3. Use Config References
# β
Good: DRY with config references
configs:
api.version: "v1"
api.prefix: "/api/${@cfg:api.version}"
router-definitions:
user-service-router:
path-prefix: "${@cfg:api.prefix}"
# π« Avoid: Duplication
router-definitions:
user-service-router:
path-prefix: "/api/v1"
order-service-router:
path-prefix: "/api/v1"
4. Document Dependencies Clearly
# β
Good: Clear dependencies
service-definitions:
order-service:
type: order-service-factory
depends-on:
- db-service # Database access
- user-service # User validation
- payment-service # Payment processing
- inventory-service # Stock management
# π« Avoid: Undocumented dependencies
service-definitions:
order-service:
type: order-service-factory
# Hidden dependencies!
5. Use Inline Router Overrides When Needed
# β
Good: Custom routes documented
router-definitions:
user-service-router:
custom:
- name: Login
method: POST
path: /auth/login
- name: Logout
method: POST
path: /auth/logout
- name: RefreshToken
method: POST
path: /auth/refresh
# π« Avoid: Overriding standard CRUD
router-definitions:
user-service-router:
custom:
- name: List
method: GET
path: /users # Unnecessary override
See Also
- Config - Configuration management
- Deploy - Deployment topology
- Service Registration - Service patterns
- Router Registration - Router patterns
Related Guides
- YAML Configuration - Configuration basics
- Deployment Strategies - Deployment patterns
- Schema Validation - Validation techniques