Documentation
¶
Index ¶
- func BuildOpenAPI(cfg *ServiceConfig, models map[string]*db.TableInfo) (*openapi3.T, error)
- func Pool(pools map[string]any, name string) any
- func PoolPG(pools map[string]any, name string) *pgxpool.Pool
- func PoolSQL(pools map[string]any, name string) *sql.DB
- func RegisterEntries(app *fiber.App, cfg *ServiceConfig, handlers *EntryHandlers, prefix string, ...) error
- func TableFor[T any](pools map[string]any, poolName, tableName string) (*db.Table[T], error)
- func WrapTransformHandler[T any](handler func(*fiber.Ctx) error, hooks EntryHooks[T]) func(*fiber.Ctx) error
- type CORSConf
- type CRUDOverrides
- type CRUDProvider
- type CronJob
- type CronJobFunc
- type CronPublish
- type CronScheduler
- type DBConfig
- type DefaultExitHooks
- type DefaultHooks
- func (DefaultHooks[T]) AfterCreate(_ context.Context, _ *T) error
- func (DefaultHooks[T]) AfterDelete(_ context.Context, _ any) error
- func (DefaultHooks[T]) AfterTransform(_ context.Context, _ any) error
- func (DefaultHooks[T]) AfterUpdate(_ context.Context, _ *T) error
- func (DefaultHooks[T]) BeforeCreate(_ context.Context, req T) (T, error)
- func (DefaultHooks[T]) BeforeDelete(_ context.Context, _ any) error
- func (DefaultHooks[T]) BeforeTransform(_ context.Context, req T) (T, error)
- func (DefaultHooks[T]) BeforeUpdate(_ context.Context, _ any, patch map[string]any) (map[string]any, error)
- type EntryDef
- type EntryHandlers
- type EntryHooks
- type ExitHandler
- type ExitHooks
- type ExitWorker
- type ExitWorkerManager
- type ListParams
- type NATSConnConf
- type NATSPublishTarget
- type OpenAPIConf
- type PaginatedResponse
- type PoolConf
- type RouteMW
- type SSEHandler
- type ServerConf
- type Service
- func (s *Service) App() *fiber.App
- func (s *Service) NATS(name string) *events.Conn
- func (s *Service) Pool(name string) any
- func (s *Service) PoolPG(name string) any
- func (s *Service) RegisterModel(name string, model any) *Service
- func (s *Service) Run() error
- func (s *Service) RunWithContext(ctx context.Context) error
- func (s *Service) WithCRUD(model string, provider CRUDProvider) *Service
- func (s *Service) WithCron(name string, handler CronJobFunc) *Service
- func (s *Service) WithExit(name string, h ExitHandler) *Service
- func (s *Service) WithExitHooks(h map[string]ExitHooks) *Service
- func (s *Service) WithHandlers(h *EntryHandlers) *Service
- func (s *Service) WithHooks(model string, hooks any) *Service
- func (s *Service) WithRest(name string, h func(*fiber.Ctx) error) *Service
- func (s *Service) WithSSE(name string, h SSEHandler) *Service
- func (s *Service) WithWS(name string, h WSHandler) *Service
- type ServiceConfig
- type StaticDef
- type StorageDef
- type StreamDef
- type SubscribeDef
- type WSHandler
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildOpenAPI ¶
BuildOpenAPI generates an OpenAPI 3.0.3 spec from the service config and registered models.
func RegisterEntries ¶
func RegisterEntries(app *fiber.App, cfg *ServiceConfig, handlers *EntryHandlers, prefix string, natsConns map[string]*events.Conn) error
RegisterEntries iterates over cfg.Entry and registers all HTTP routes on app. natsConns is optional — used for auto-publishing on nats_publish targets.
func WrapTransformHandler ¶
func WrapTransformHandler[T any](handler func(*fiber.Ctx) error, hooks EntryHooks[T]) func(*fiber.Ctx) error
WrapTransformHandler wraps a REST handler with BeforeTransform/AfterTransform hooks. The hooks must implement EntryHooks[T] where T is the request model. BeforeTransform parses the request body into T, calls the hook, stores the result in c.Locals("transformed"), then executes the handler. AfterTransform is called with the response body after the handler completes.
Usage:
svc.WithRest("onTransform", runtime.WrapTransformHandler(
func(c *fiber.Ctx) error {
input := c.Locals("transformed").(Product)
return c.JSON(fiber.Map{"name": input.Name})
},
&ProductHooks{},
))
Types ¶
type CRUDOverrides ¶
type CRUDProvider ¶
type CRUDProvider interface {
List(ctx *fiber.Ctx, params ListParams) error
Get(ctx *fiber.Ctx, id string) error
Create(ctx *fiber.Ctx, body []byte) error
Update(ctx *fiber.Ctx, id string, body []byte) error
Delete(ctx *fiber.Ctx, id string) error
}
CRUDProvider abstracts typed Table[T] operations for the router.
func NewCRUDProvider ¶
func NewCRUDProvider[T any](table *db.Table[T], hooks EntryHooks[T]) CRUDProvider
NewCRUDProvider wraps a db.Table[T] (PostgreSQL) into a CRUDProvider.
func NewMySQLCRUDProvider ¶
func NewMySQLCRUDProvider[T any](table *db.MySQLTable[T], hooks EntryHooks[T]) CRUDProvider
func NewTursoCRUDProvider ¶
func NewTursoCRUDProvider[T any](table *db.TursoTable[T], hooks EntryHooks[T]) CRUDProvider
type CronJob ¶
type CronJob struct {
Name string `json:"name"`
Schedule string `json:"schedule"`
Mode string `json:"mode,default=nats"` // nats, handler, internal
Publish *CronPublish `json:"publish,optional"`
Handler string `json:"handler,optional"`
}
type CronJobFunc ¶
CronJobFunc is a handler called on cron schedule. Returns error on failure.
type CronPublish ¶
type CronScheduler ¶
type CronScheduler struct {
// contains filtered or unexported fields
}
CronScheduler manages periodic jobs defined in cron:[].
func NewCronScheduler ¶
func NewCronScheduler() *CronScheduler
NewCronScheduler creates a new scheduler.
func (*CronScheduler) AddAll ¶
func (s *CronScheduler) AddAll(cronDefs []CronJob, natsConns map[string]*events.Conn, handlers map[string]CronJobFunc) error
AddAll registers all cron jobs from config.
func (*CronScheduler) AddJob ¶
func (s *CronScheduler) AddJob(cfg CronJob, natsConn *events.Conn, handler CronJobFunc) error
AddJob registers a cron job from config. handler is only used for mode=handler. nats is used for mode=nats to publish on schedule.
func (*CronScheduler) Start ¶
func (s *CronScheduler) Start()
Start begins executing scheduled jobs.
func (*CronScheduler) Stop ¶
func (s *CronScheduler) Stop()
Stop stops the scheduler and waits for running jobs to finish.
type DBConfig ¶
type DefaultExitHooks ¶
type DefaultExitHooks struct{}
func (DefaultExitHooks) OnSuccess ¶
func (DefaultExitHooks) OnSuccess(_ context.Context)
type DefaultHooks ¶
type DefaultHooks[T any] struct{}
func (DefaultHooks[T]) AfterCreate ¶
func (DefaultHooks[T]) AfterCreate(_ context.Context, _ *T) error
func (DefaultHooks[T]) AfterDelete ¶
func (DefaultHooks[T]) AfterDelete(_ context.Context, _ any) error
func (DefaultHooks[T]) AfterTransform ¶
func (DefaultHooks[T]) AfterTransform(_ context.Context, _ any) error
func (DefaultHooks[T]) AfterUpdate ¶
func (DefaultHooks[T]) AfterUpdate(_ context.Context, _ *T) error
func (DefaultHooks[T]) BeforeCreate ¶
func (DefaultHooks[T]) BeforeCreate(_ context.Context, req T) (T, error)
func (DefaultHooks[T]) BeforeDelete ¶
func (DefaultHooks[T]) BeforeDelete(_ context.Context, _ any) error
func (DefaultHooks[T]) BeforeTransform ¶
func (DefaultHooks[T]) BeforeTransform(_ context.Context, req T) (T, error)
type EntryDef ¶
type EntryDef struct {
Type string `json:"type"` // crud, rest, webhook, websocket, sse, file
Method string `json:"method,optional"`
Path string `json:"path,optional"`
Handler string `json:"handler,optional"`
Auth bool `json:"auth,optional"`
DB string `json:"db,optional"` // references database name
// CRUD
Model string `json:"model,optional"`
Table string `json:"table,optional"`
Resource string `json:"resource,optional"`
Overrides *CRUDOverrides `json:"overrides,optional"`
// NATS publish after entry
NATSPublish []NATSPublishTarget `json:"nats_publish,optional"`
// File
AllowedTypes []string `json:"allowed_types,optional"`
MaxSize string `json:"max_size,optional"`
Storage *StorageDef `json:"storage,optional"`
}
type EntryHandlers ¶
type EntryHandlers struct {
Rest map[string]func(*fiber.Ctx) error
WS map[string]WSHandler
SSE map[string]SSEHandler
CRUD map[string]CRUDProvider
Storage map[string]server.StorageBackend
Transform map[string]any // handler name → EntryHooks[T] (untyped due to generics)
}
EntryHandlers holds all named handler functions registered by the user.
type EntryHooks ¶
type EntryHooks[T any] interface { BeforeCreate(ctx context.Context, req T) (T, error) AfterCreate(ctx context.Context, entity *T) error BeforeUpdate(ctx context.Context, id any, patch map[string]any) (map[string]any, error) AfterUpdate(ctx context.Context, entity *T) error BeforeDelete(ctx context.Context, id any) error AfterDelete(ctx context.Context, id any) error BeforeTransform(ctx context.Context, req T) (T, error) AfterTransform(ctx context.Context, result any) error }
EntryHooks defines lifecycle callbacks for entry endpoints (HTTP).
type ExitHooks ¶
type ExitHooks interface {
OnMessage(ctx context.Context, msg []byte) ([]byte, error)
OnSuccess(ctx context.Context)
OnError(ctx context.Context, err error)
}
ExitHooks defines lifecycle callbacks for exit workers (NATS).
type ExitWorker ¶
type ExitWorker struct {
Name string `json:"name"`
Subscribe SubscribeDef `json:"subscribe"`
Handler string `json:"handler"`
MaxConcurrent int `json:"max_concurrent,default=1"`
DB string `json:"db,optional"`
Reply bool `json:"reply,optional"`
ReplyTimeout string `json:"reply_timeout,default=30s"`
PullBatch int `json:"pull_batch,optional"`
PullMaxWait string `json:"pull_max_wait,optional"`
ConsumerMode string `json:"consumer_mode,optional"` // push or pull
}
func (*ExitWorker) Validate ¶
func (e *ExitWorker) Validate() error
type ExitWorkerManager ¶
type ExitWorkerManager struct {
// contains filtered or unexported fields
}
func NewExitWorkerManager ¶
func NewExitWorkerManager() *ExitWorkerManager
func (*ExitWorkerManager) Shutdown ¶
func (m *ExitWorkerManager) Shutdown(timeout time.Duration)
func (*ExitWorkerManager) Start ¶
func (m *ExitWorkerManager) Start(ctx context.Context, exitDefs []ExitWorker, natsConns map[string]*events.Conn, handlers map[string]ExitHandler, hooks map[string]ExitHooks) error
type ListParams ¶
ListParams holds query parameters for list endpoints.
type NATSConnConf ¶
type NATSConnConf struct {
Name string `json:"name"`
URL string `json:"url"`
MaxReconnects int `json:"max_reconnects,default=10"`
ReconnectWait string `json:"reconnect_wait,default=2s"`
Timeout string `json:"timeout,default=5s"`
RetryOnFail bool `json:"retry_on_fail,default=true"`
Streams []StreamDef `json:"streams,optional"`
}
func (*NATSConnConf) Validate ¶
func (n *NATSConnConf) Validate() error
type NATSPublishTarget ¶
type OpenAPIConf ¶
type OpenAPIConf struct {
Enabled bool `json:"enabled,optional"`
Version string `json:"version,default=1.0.0"`
SpecPath string `json:"spec_path,default=/openapi.json"`
DocsPath string `json:"docs_path,default=/docs"`
Theme string `json:"theme,default=moon"`
DarkMode bool `json:"dark_mode,default=true"`
}
type PaginatedResponse ¶
type PaginatedResponse struct {
Data any `json:"data"`
Total int64 `json:"total"`
Page int `json:"page"`
Size int `json:"size"`
}
PaginatedResponse is used by tableCRUD.List.
type PoolConf ¶
type PoolConf struct {
MaxConns int32 `json:"max_conns,default=10"`
MinConns int32 `json:"min_conns,default=2"`
MaxConnLifetime string `json:"max_conn_lifetime,optional"`
MaxConnIdleTime string `json:"max_conn_idle_time,optional"`
HealthCheckPeriod string `json:"health_check_period,optional"`
ReservedConns int32 `json:"reserved_conns,default=10"`
}
type SSEHandler ¶
SSEHandler is called when an SSE client connects.
type ServerConf ¶
type ServerConf struct {
Host string `json:"host,default=0.0.0.0"`
Prefork bool `json:"prefork,optional"`
BodyLimit int `json:"body_limit,default=4194304"`
Timeout string `json:"timeout,default=30s"`
MaxConns int `json:"max_conns,default=1000"`
MaxBytes int `json:"max_bytes,default=4194304"`
MetricsPath string `json:"metrics_path,default=/metrics"`
HealthPath string `json:"health_path,default=/health"`
ShutdownTimeout string `json:"shutdown_timeout,default=10s"`
RecoverStack bool `json:"recover_stack,default=true"`
APIPrefix string `json:"api_prefix,default=/api/v1"`
CORS *CORSConf `json:"cors,optional"`
Middleware []RouteMW `json:"middleware,optional"`
Static []StaticDef `json:"static,optional"`
MaxConnLimit int `json:"max_conn_limit,default=1000"`
OpenAPI *OpenAPIConf `json:"openapi,optional"`
}
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is the main runtime orchestrator. It reads a service YAML, initializes databases, NATS connections, entry endpoints, and optionally exit workers and cron jobs.
func (*Service) RegisterModel ¶
RegisterModel registers a model for OpenAPI schema generation. Usage: svc.RegisterModel("Product", (*Product)(nil)).
func (*Service) RunWithContext ¶
RunWithContext starts the service with a parent context.
func (*Service) WithCRUD ¶
func (s *Service) WithCRUD(model string, provider CRUDProvider) *Service
WithCRUD registers a CRUD provider for a model name.
func (*Service) WithCron ¶
func (s *Service) WithCron(name string, handler CronJobFunc) *Service
WithCron registers a cron handler by name (for mode=handler).
func (*Service) WithExit ¶
func (s *Service) WithExit(name string, h ExitHandler) *Service
WithExit registers an exit handler by name (for NATS workers).
func (*Service) WithExitHooks ¶
WithExitHooks registers exit hooks by worker name.
func (*Service) WithHandlers ¶
func (s *Service) WithHandlers(h *EntryHandlers) *Service
WithHandlers registers all entry handler functions.
func (*Service) WithHooks ¶
WithHooks registers entry hooks for a model. The hooks are applied to the corresponding CRUD provider if one has been registered for that model.
type ServiceConfig ¶
type ServiceConfig struct {
Name string `json:"name"`
Port int `json:"port,default=8080"`
Server ServerConf `json:"server,optional"`
Databases []DBConfig `json:"databases,optional"`
NATS []NATSConnConf `json:"nats,optional"`
Entry []EntryDef `json:"entry,optional"`
Exit []ExitWorker `json:"exit,optional"`
Cron []CronJob `json:"cron,optional"`
}
func LoadConfig ¶
func LoadConfig(path string) (*ServiceConfig, error)
type StorageDef ¶
type StorageDef struct {
Mode string `json:"mode"` // s3, local
Bucket string `json:"bucket,optional"`
Path string `json:"path,optional"`
Region string `json:"region,optional"`
Endpoint string `json:"endpoint,optional"`
AccessKey string `json:"access_key,optional"`
SecretKey string `json:"secret_key,optional"`
}