Documentation
¶
Index ¶
- Constants
- Variables
- func BindQuery(r *nethttp.Request, v any) error
- func CollectHooks(v any) lifecycle.Hooks
- func Controllers(constructors ...any) module.ModuleOption
- func Dynamic(factory func(...any) module.Module, opts ...any) module.ModuleOption
- func Get[T any](ctx *Context, key string) T
- func HookedController(fn any) any
- func Hooks(hooks ...HookOption) *lifecycle.HookRegistry
- func Imports(modules ...module.Module) module.ModuleOption
- func Middlewares(constructors ...any) module.ModuleOption
- func ModuleHooks(opts ...ModuleHookOption) *lifecycle.ModuleHookRegistry
- func MustResolve[T any](a *App) T
- func NewModule(name string, opts ...module.ModuleOption) module.Module
- func OnModuleDestroy(fn func() error) module.ModuleOption
- func OnModuleInit(fn func() error) module.ModuleOption
- func Providers(providers ...any) module.ModuleOption
- func Query(r *nethttp.Request, key string) string
- func QueryDefault(r *nethttp.Request, key, def string) string
- func QueryInt(r *nethttp.Request, key string, def int) int
- func Resolve[T any](a *App) (T, error)
- func ValidatedBody[T any](ctx *Context) *T
- func WithModuleHooks(opts ...ModuleHookOption) module.ModuleOption
- type App
- type ChainRouter
- type Context
- type Controller
- type DIError
- type ErrAppAlreadyStarted
- type ErrCircularDependency
- type ErrControllerBinding
- type ErrMissingDependency
- type ExceptionFilter
- type Guard
- type HandlerFunc
- type HasRole
- type HookFunc
- type HookOption
- type HookRegistry
- type HookRegistryRef
- type Interceptor
- type LifecycleHook
- type ListMeta
- type ListQuery
- type ListResponse
- type Logger
- type LoggerField
- type LoggerOption
- type LoggerType
- type Middleware
- type Module
- type ModuleHookOption
- type Option
- func OnStart(hook LifecycleHook) Option
- func OnStop(hook LifecycleHook) Option
- func WithAddr(addr string) Option
- func WithAutoPort() Option
- func WithDebug(debug bool) Option
- func WithGracefulShutdown(timeout time.Duration) Option
- func WithJSON() Option
- func WithLogger(l Logger) Option
- func WithMiddleware(mw ...Middleware) Option
- func WithParallelHooks() Option
- func WithRouter(r Router) Option
- type PageMeta
- type PageResponse
- type Pipe
- type Provider
- func Export(p Provider) Provider
- func Factory[T any](fn any, opts ...ProviderOption) Provider
- func HookedFactory[T any](fn any) Provider
- func HookedSingleton[T any](fn any) Provider
- func Transient[T any](fn any, opts ...ProviderOption) Provider
- func Value[T any](instance T, opts ...ProviderOption) Provider
- type ProviderOption
- type Registerable
- type RouteBuilder
- type Router
- type Throttler
Constants ¶
const ( // DefaultPort is the default HTTP port for the server. DefaultPort = ":8080" // DefaultGracefulTimeout is the default timeout for graceful shutdown. DefaultGracefulTimeout = 10 * time.Second )
const ( // LoggerText enables human-readable text logging. LoggerText = logger.TypeText // LoggerJSON enables structured JSON logging. LoggerJSON = logger.TypeJSON )
const ValidatedBodyKey = http.ValidatedBodyKey
ValidatedBodyKey is the context key where ValidationPipe stores the validated body. Prefer ValidatedBody[T] over accessing this key directly.
Variables ¶
var ErrBadRequest = http.ErrBadRequest
ErrBadRequest is wrapped by param-parsing pipes (UUIDPipe, ParseIntPipe, ParseBoolPipe) when a path parameter is invalid. Detect it with errors.Is(err, ligo.ErrBadRequest).
var ErrGuardDenied = http.ErrGuardDenied
ErrGuardDenied is returned by the route handler when a Guard returns (false, nil). ExceptionFilters detect it with errors.Is(err, ligo.ErrGuardDenied) and typically map to HTTP 403.
Functions ¶
func BindQuery ¶ added in v0.8.0
BindQuery decodes URL query parameters into the struct pointed to by v. Fields are matched by the `query:"name"` tag; untagged fields are ignored. Supported field kinds: string, signed/unsigned ints, bool, floats, and slices of those (accepted as repeated params or comma-separated).
Example:
type UserFilter struct {
Name string `query:"name"`
Email string `query:"email"`
Sort string `query:"sort"`
}
var f UserFilter
if err := ligo.BindQuery(ctx.Request(), &f); err != nil { ... }
func CollectHooks ¶ added in v0.5.0
CollectHooks is the internal hook collection function. Re-exported for internal use.
func Controllers ¶
func Controllers(constructors ...any) module.ModuleOption
Controllers adds controller constructors that receive dependencies via DI. Each constructor is called with resolved dependencies and must return a Controller.
Example:
ligo.Controllers(
func(svc *UserService) ligo.Controller {
return &UserController{service: svc}
},
)
func Dynamic ¶
Dynamic creates a module option for dynamic modules with configuration options. The factory function receives the options and returns a configured module. This is useful for creating modules that need runtime configuration.
Type safety: opts is intentionally typed as ...any. This is the framework's escape hatch for runtime-configured modules; the factory is responsible for type-asserting each option. For statically-known configuration prefer a typed constructor that returns a Module directly — no Dynamic needed:
// Prefer this when configuration is fixed at compile time:
func ConfigModule(folder string) ligo.Module {
return ligo.NewModule("config", ligo.Providers(NewConfigService(folder)))
}
// Use Dynamic only when the factory must accept heterogeneous opts:
func RegisterConfigModule(folder string) ligo.Module {
return ligo.NewModule("config",
ligo.Dynamic(NewConfigModule, folder),
)
}
func Get ¶ added in v0.3.0
Get retrieves a context value set by a pipe and asserts it to type T. Returns the zero value of T if the key is missing or the type does not match. Use this instead of ctx.Get(key).(T) to avoid a manual type assertion.
Example:
func (c *UserController) GetByID(ctx *ligo.Context) error {
id := ligo.Get[int](ctx, "id") // set by ParseIntPipe("id")
active := ligo.Get[bool](ctx, "active") // set by ParseBoolPipe("active")
uuid := ligo.Get[string](ctx, "id") // set by UUIDPipe("id")
}
func HookedController ¶ added in v0.5.0
HookedController wraps a controller constructor to enable explicit hook registration via a Register method on the controller instance. This provides compile-time safety for hook method expressions, similar to HookedFactory for providers.
The controller instance can implement:
type Registerable interface {
Register(*lifecycle.HookRegistry)
}
Example:
type UserController struct {
userService *UserService
log ligo.Logger
}
func NewUserController(svc *UserService, log ligo.Logger) *UserController {
return &UserController{userService: svc, log: log}
}
func (c *UserController) Initialize() error {
c.log.Info("User controller initializing")
return nil
}
func (c *UserController) Ready() error {
c.log.Info("User controller ready")
return nil
}
// Register method enables compile-time safe hook registration
func (c *UserController) Register(r *lifecycle.HookRegistry) {
r.OnInit(c.Initialize) // Method expression - compile-time checked
r.OnBootstrap(c.Ready) // If Ready doesn't exist → compile error
}
// Controller registration
ligo.HookedController(NewUserController)
func Hooks ¶ added in v0.5.0
func Hooks(hooks ...HookOption) *lifecycle.HookRegistry
Hooks creates a new hook registry for explicit lifecycle hook registration. Use with providers and controllers:
ligo.Factory[*Database](NewDatabase,
ligo.Hooks(
ligo.OnInit(func(db *Database) error { ... }),
ligo.BeforeShutdown(func(db *Database) error { ... }),
),
)
func Imports ¶
func Imports(modules ...module.Module) module.ModuleOption
Imports adds child modules to this module. Child modules can access exported providers from this module.
Example:
ligo.Imports(
database.Module(),
auth.Module(),
)
func Middlewares ¶
func Middlewares(constructors ...any) module.ModuleOption
Middlewares adds middleware constructors that receive dependencies via DI. Each constructor is called with resolved dependencies and must return a Middleware.
Example:
ligo.Middlewares(
func(logger *Logger) ligo.Middleware {
return LoggingMiddleware(logger)
},
)
func ModuleHooks ¶ added in v0.5.0
func ModuleHooks(opts ...ModuleHookOption) *lifecycle.ModuleHookRegistry
ModuleHooks creates module-level lifecycle hooks. Use with NewModule:
ligo.NewModule("user",
ligo.Providers(...),
ligo.ModuleHooks(
ligo.ModuleInit(func() error { ... }),
ligo.ModuleDestroy(func() error { ... }),
),
)
func MustResolve ¶ added in v0.10.0
MustResolve returns an instance of type T from the application container. Panics on any resolution failure. Use Resolve when you can handle the error. Must be called after Run() has built the container.
func NewModule ¶
func NewModule(name string, opts ...module.ModuleOption) module.Module
NewModule creates a new module with the given name and options. The name should be unique and descriptive (e.g., "user", "auth", "database").
Example:
func Module() ligo.Module {
return ligo.NewModule("user",
ligo.Providers(...),
ligo.Controllers(...),
)
}
func OnModuleDestroy ¶
func OnModuleDestroy(fn func() error) module.ModuleOption
OnModuleDestroy adds a hook to run when the module is destroyed. Hooks are executed in reverse order during application shutdown.
Example:
ligo.OnModuleDestroy(func() error {
return database.Close()
})
func OnModuleInit ¶
func OnModuleInit(fn func() error) module.ModuleOption
OnModuleInit adds a hook to run when the module is initialized. Hooks are executed after all providers are registered but before the server starts.
Example:
ligo.OnModuleInit(func() error {
return database.Connect()
})
func Providers ¶
func Providers(providers ...any) module.ModuleOption
Providers adds providers to the module. Providers can be Values, Factories, or Transients that are registered in the DI container for this module.
Example:
ligo.Providers(
ligo.Value("config-value"),
ligo.Factory[*UserService](NewUserService),
ligo.Transient[*RequestContext](NewRequestContext),
)
func QueryDefault ¶ added in v0.8.0
QueryDefault returns the query value or def when absent/empty.
func QueryInt ¶ added in v0.8.0
QueryInt parses a query value as int, returning def on missing/invalid.
func Resolve ¶ added in v0.10.0
Resolve returns an instance of type T from the application container. Returns the zero value and an error when the type cannot be resolved (missing provider, ambiguous interface, circular dependency, factory error). Must be called after Run() has built the container.
Example:
user, err := ligo.Resolve[*UserService](app)
if err != nil { /* handle */ }
func ValidatedBody ¶
ValidatedBody retrieves the validated body stored by ValidationPipe[T]. Panics with a clear message if ValidationPipe was not added to the route.
Example:
func (c *UserController) Create(ctx *ligo.Context) error {
input := ligo.ValidatedBody[CreateUserInput](ctx)
// input is *CreateUserInput, guaranteed non-nil
}
func WithModuleHooks ¶ added in v0.5.0
func WithModuleHooks(opts ...ModuleHookOption) module.ModuleOption
WithModuleHooks adds explicit lifecycle hooks to the module. This is an alternative to OnModuleInit/OnModuleDestroy for more control.
Example:
ligo.NewModule("user",
ligo.Providers(...),
ligo.WithModuleHooks(
ligo.OnInit(func() error { ... }),
ligo.OnDestroy(func() error { ... }),
),
)
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App represents a Ligo application with dependency injection, module management, and HTTP server capabilities.
func New ¶
New creates a new Ligo application with the given options. Options include WithRouter, WithAddr, WithMiddleware, OnStart, and OnStop.
Example:
app := ligo.New(
ligo.WithRouter(echo.NewAdapter()),
ligo.WithAddr(":8080"),
)
func (*App) Provide ¶
Provide registers global providers that are available across all modules. Providers must be registered before calling Run(). Panics if called after the application has started.
Example:
app.Provide(
ligo.Value("config-value"),
ligo.Factory[*Config](NewConfig),
)
func (*App) Register ¶
Register registers one or more modules with the application. Modules must be registered before calling Run(). Panics if called after the application has started.
Example:
app.Register(
user.Module(),
auth.Module(),
)
func (*App) Run ¶
Run starts the HTTP server and blocks until the server is shut down. It builds the DI container, registers all modules and providers, executes OnModuleInit hooks, starts the server, and waits for shutdown. On shutdown, it executes OnModuleDestroy and OnStop hooks.
Example:
if err := app.Run(); err != nil {
log.Fatal(err)
}
type ChainRouter ¶
type ChainRouter = http.ChainRouter
ChainRouter provides fluent chain methods for building routes. It allows chaining method calls for configuring routes.
func NewChainRouter ¶
func NewChainRouter(r Router) ChainRouter
NewChainRouter wraps a Router with chain methods. Example:
cr := ligo.NewChainRouter(router)
cr.GET("/", handler).Guard(authGuard).Handle()
type Context ¶
Context wraps HTTP request/response for handlers, providing methods for accessing request data, binding bodies, and sending responses.
type Controller ¶
type Controller = http.Controller
Controller defines how HTTP routes are registered for a module. Controllers receive dependencies via DI and register routes using the Router.
type ErrAppAlreadyStarted ¶
type ErrAppAlreadyStarted struct{}
ErrAppAlreadyStarted is returned when trying to modify an app after Run() has been called. This includes calling Register() or Provide() after the application has started.
func (*ErrAppAlreadyStarted) Error ¶
func (e *ErrAppAlreadyStarted) Error() string
type ErrCircularDependency ¶
type ErrCircularDependency = di.ErrCircularDependency
ErrCircularDependency is returned when a circular dependency is detected in the provider graph.
type ErrControllerBinding ¶
type ErrControllerBinding = http.ErrControllerBinding
ErrControllerBinding is returned when a controller's dependency chain cannot be fully resolved.
type ErrMissingDependency ¶
type ErrMissingDependency = di.ErrMissingDependency
ErrMissingDependency is returned when a required dependency cannot be found in the di.
type ExceptionFilter ¶
type ExceptionFilter = http.ExceptionFilter
ExceptionFilter handles errors and converts them to HTTP responses. ExceptionFilters are called when handlers or other components return errors.
type Guard ¶
Guard determines if a request should proceed (authorization). A Guard returns (true, nil) to allow the request, or (false, error) to deny it.
func AdminGuard ¶
AdminGuard is a convenience guard that checks for admin role. Usage: cr.DELETE("/:id", c.Delete).Guard(ligo.AdminGuard("user"))
func RolesGuard ¶
RolesGuard creates a guard that checks if the user has one of the required roles. Usage: cr.GET("", c.List).Guard(ligo.RolesGuard("user", "admin"))
func ThrottleGuard ¶
ThrottleGuard creates a rate-limiting guard using a process-wide in-memory counter store. New code should prefer NewThrottler so each app has its own state and can clean up on shutdown. Usage: cr.POST("", c.Create).Guard(ligo.ThrottleGuard("ip", 10, time.Minute))
type HandlerFunc ¶
type HandlerFunc = http.HandlerFunc
HandlerFunc is the standard handler signature for route handlers. It receives a Context and returns an error.
type HookOption ¶ added in v0.5.0
type HookOption func(*lifecycle.HookRegistry)
HookOption is a functional option for configuring hooks.
func BeforeShutdown ¶ added in v0.5.0
func BeforeShutdown(fn func() error) HookOption
BeforeShutdown creates a hook option for BeforeApplicationShutdown.
func OnBootstrap ¶ added in v0.5.0
func OnBootstrap(fn func() error) HookOption
OnBootstrap creates a hook option for OnApplicationBootstrap.
func OnDestroy ¶ added in v0.5.0
func OnDestroy(fn func() error) HookOption
OnDestroy creates a hook option for OnModuleDestroy.
func OnInit ¶ added in v0.5.0
func OnInit(fn func() error) HookOption
OnInit creates a hook option for OnModuleInit.
func OnShutdown ¶ added in v0.5.0
func OnShutdown(fn func() error) HookOption
OnShutdown creates a hook option for OnApplicationShutdown.
type HookRegistry ¶ added in v0.5.0
type HookRegistry = lifecycle.HookRegistry
HookRegistry stores lifecycle hooks for a specific type. Use Hooks() to create a new registry.
type HookRegistryRef ¶ added in v0.5.0
type HookRegistryRef = *lifecycle.HookRegistry
HookRegistryRef is a pointer to HookRegistry for use in Register methods. This is a convenience type alias for method receivers.
type Interceptor ¶
type Interceptor = http.Interceptor
Interceptor wraps the entire request/response cycle. Interceptors can modify the request before processing and the response after.
func LoggingInterceptor ¶
func LoggingInterceptor(logFunc func(start time.Time, ctx *Context, err error)) Interceptor
LoggingInterceptor creates an interceptor that logs request details. Usage: cr.GET("", c.List).Intercept(ligo.LoggingInterceptor(func(start time.Time, ctx *Context, err error) { ... }))
func TimeoutInterceptor ¶
func TimeoutInterceptor(timeout time.Duration) Interceptor
TimeoutInterceptor creates an interceptor that enforces a timeout. Usage: cr.GET("", c.List).Intercept(ligo.TimeoutInterceptor(5 * time.Second))
type LifecycleHook ¶
LifecycleHook is a function called during app lifecycle events. The ctx parameter is context.Context for OnStart/OnStop hooks.
type ListMeta ¶ added in v0.7.0
ListMeta is the meta block for plain list responses (no pagination).
type ListQuery ¶ added in v0.7.0
ListQuery captures common pagination query params (?page=, ?per_page=).
func Paginate ¶ added in v0.8.0
Paginate is a one-shot helper: ParseListQuery + Normalize. Honors ?per_page=0 (LIMIT 0); falls back to defaultPerPage only when ?per_page= is absent. Caps PerPage at maxPerPage when maxPerPage > 0.
func ParseListQuery ¶ added in v0.7.0
ParseListQuery reads ?page= and ?per_page= from the request. Missing or invalid values stay zero; call Normalize to apply defaults.
Example:
func (c *UserController) List(ctx *ligo.Context) error {
q := ligo.ParseListQuery(ctx.Request())
q.Normalize(20, 100) // default 20, max 100
users, total, err := c.repo.FindPage(ctx.Request().Context(), q.PerPage, q.Offset())
if err != nil { return err }
return ctx.Paginated(users, q.Page, q.PerPage, total)
}
type ListResponse ¶ added in v0.7.0
type ListResponse = http.ListResponse
ListResponse is { "data": [...], "meta": { "count": N } }.
func NewListResponse ¶ added in v0.7.0
func NewListResponse(items any) ListResponse
NewListResponse builds a ListResponse, coercing nil slices to [].
type Logger ¶
Logger is the interface for framework logging.
func NewLogger ¶
func NewLogger(opts ...LoggerOption) Logger
NewLogger creates a new logger. Default is text mode for development.
Example:
logger := ligo.NewLogger(
ligo.WithLoggerJSON(),
ligo.WithLoggerDebug(),
)
func NoopLogger ¶ added in v0.11.0
func NoopLogger() Logger
NoopLogger returns a Logger that discards every call. Convenient for tests that want to bypass log spam without importing internal/core/logger.
type LoggerField ¶
LoggerField is a key-value pair for structured logging.
type LoggerOption ¶
type LoggerOption = logger.LoggerOption
LoggerOption configures the logger.
func WithLoggerJSON ¶
func WithLoggerJSON() LoggerOption
WithLoggerJSON sets JSON output format for production.
func WithLoggerProduction ¶
func WithLoggerProduction() LoggerOption
WithLoggerProduction enables JSON logging (alias for WithLoggerJSON).
func WithLoggerText ¶
func WithLoggerText() LoggerOption
WithLoggerText sets text output format (default).
type Middleware ¶
type Middleware = http.Middleware
Middleware is a function that wraps a handler to add pre/post processing. Middleware can modify the request, response, or short-circuit the handler chain.
type Module ¶
Module represents a self-contained unit of functionality that encapsulates providers, controllers, middleware, and lifecycle hooks.
type ModuleHookOption ¶ added in v0.5.0
type ModuleHookOption func(*lifecycle.ModuleHookRegistry)
ModuleHookOption is a functional option for module-level hooks.
func ModuleDestroy ¶ added in v0.5.0
func ModuleDestroy(fn func() error) ModuleHookOption
ModuleDestroy creates a module-level hook option for OnModuleDestroy.
func ModuleInit ¶ added in v0.5.0
func ModuleInit(fn func() error) ModuleHookOption
ModuleInit creates a module-level hook option for OnModuleInit.
type Option ¶
type Option func(*options)
Option configures the App.
func WithAutoPort ¶
func WithAutoPort() Option
WithAutoPort enables automatic port increment if the default port is already in use.
func WithGracefulShutdown ¶
WithGracefulShutdown enables graceful shutdown on SIGINT/SIGTERM.
func WithLogger ¶
WithLogger overrides the framework logger. Useful in tests (pass ligo.NoopLogger() to silence startup/shutdown chatter) and for binaries that want to share a logger across the app and their own subsystems. nil is treated as "no override" — keeps the default constructed logger.
func WithMiddleware ¶
func WithMiddleware(mw ...Middleware) Option
WithMiddleware adds global middleware.
func WithParallelHooks ¶ added in v0.10.0
func WithParallelHooks() Option
WithParallelHooks runs provider OnInit and OnBootstrap hooks concurrently. Default is sequential execution in registration order — opt in only when the application has many independent providers whose startup work is I/O-bound (DB pools, remote handshakes) and order does not matter.
Parallel execution does not guarantee any ordering between hooks and surfaces a single aggregated error if any hook fails.
type PageResponse ¶ added in v0.7.0
type PageResponse = http.PageResponse
PageResponse is { "data": [...], "meta": { page, per_page, total, total_pages } }.
func NewPageResponse ¶ added in v0.7.0
func NewPageResponse(items any, page, perPage int, total int64) PageResponse
NewPageResponse builds a PageResponse, coercing nil slices to [] and computing total_pages from total / perPage.
type Pipe ¶
Pipe transforms input data before it reaches the handler. Pipes are used for validation, parsing, and data transformation.
func ParseBoolPipe ¶
ParseBoolPipe parses a string parameter to bool. Accepts: "true", "false", "1", "0" (case-insensitive).
Example:
cr.GET("/:active", c.Get).Pipe(ligo.ParseBoolPipe("active"))
func ParseIntPipe ¶
ParseIntPipe parses a string parameter to int. Returns an error if the parameter cannot be parsed as an integer.
Example:
cr.GET("/:id", c.Get).Pipe(ligo.ParseIntPipe("id"))
func TrimPipe ¶
TrimPipe removes leading and trailing whitespace from a string parameter.
Example:
cr.POST("", c.Create).Pipe(ligo.TrimPipe("name"))
func UUIDPipe ¶
UUIDPipe validates that a string parameter is a valid UUID format. Returns an error if the parameter is not a valid UUID.
Example:
cr.GET("/:uuid", c.Get).Pipe(ligo.UUIDPipe("uuid"))
func ValidationPipe ¶
ValidationPipe validates a struct using struct tags. It uses the "validate" tag and requires the go-playground/validator package.
Example:
type CreateUserInput struct {
Name string `validate:"required,min=3"`
Email string `validate:"required,email"`
}
cr.POST("", c.Create).Pipe(ligo.ValidationPipe(&CreateUserInput{}))
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider represents a dependency provider that can be registered in the DI di. Providers can be eager values or factory functions.
func Export ¶
Export marks a provider as exported, making it visible to sibling modules. This allows providers to be shared across modules without being global.
Example:
ligo.Export(ligo.Factory[*Database](func() *Database {
return NewDatabase()
}))
func Factory ¶
func Factory[T any](fn any, opts ...ProviderOption) Provider
Factory registers a factory function that produces a singleton. The function can have dependencies as parameters; they are auto-injected. The factory is called once, and the result is cached for subsequent resolutions.
Hooks can be attached using WithHooks:
ligo.Factory[*UserService](func(repo *UserRepository) *UserService {
return NewUserService(repo)
}, ligo.WithHooks(
ligo.OnInit(func(svc *UserService) error { ... }),
))
func HookedFactory ¶ added in v0.5.0
HookedFactory registers a factory function and enables explicit hook registration via a Register method on the created instance. This provides compile-time safety for hook method expressions.
The created instance can implement:
type Registerable interface {
Register(*lifecycle.HookRegistry)
}
Example:
type Database struct {
db *sql.DB
}
func (d *Database) Connect() error {
d.db = sql.Open("postgres", "dsn")
return nil
}
func (d *Database) Close() error {
return d.db.Close()
}
// Register method enables compile-time safe hook registration
func (d *Database) Register(r *lifecycle.HookRegistry) {
r.OnInit(d.Connect) // Method expression - compile-time checked
r.OnShutdown(d.Close) // If Close doesn't exist → compile error
}
// Provider registration
ligo.HookedFactory(NewDatabase)
func HookedSingleton ¶ added in v0.9.0
HookedSingleton is like HookedFactory but marks the provider for eager resolution at application startup. Use it for providers whose only purpose is to attach lifecycle hooks (RPC handler registrations, background workers, schedulers) — where nothing else in the DI graph depends on the type, so a plain HookedFactory would never be instantiated and its Register method would never fire.
Example:
// OrderMessaging only exists to bind RPC handlers in OnBootstrap. No // other provider depends on it, so HookedFactory would be a no-op. ligo.HookedSingleton[*OrderMessaging](NewOrderMessaging)
Eager providers are resolved after all modules have been built and before any OnInit / OnBootstrap hook executes, so their dependencies (and the hooks they register) participate normally in the lifecycle.
func Transient ¶
func Transient[T any](fn any, opts ...ProviderOption) Provider
Transient registers a factory function that produces a new instance on each resolve. Unlike Factory, the factory function is called every time the type is resolved. Dependencies are still auto-injected.
Example:
ligo.Transient[*RequestContext](func() *RequestContext {
return NewRequestContext()
}, ligo.WithHooks(
ligo.OnInit(func(ctx *RequestContext) error { ... }),
))
func Value ¶
func Value[T any](instance T, opts ...ProviderOption) Provider
Value registers a pre-built instance as a singleton. The same instance will be returned for all resolutions of this type.
Example:
ligo.Value("config-value")
ligo.Value(&Config{Debug: true})
With hooks:
ligo.Value(&Database{db: db}, ligo.WithHooks(
ligo.OnShutdown(func(db *Database) error { return db.Close() }),
))
func (Provider) Hooks ¶ added in v0.5.0
func (p Provider) Hooks() *lifecycle.HookRegistry
Hooks returns the hook registry if set (for internal use).
func (Provider) IsEagerResolve ¶ added in v0.9.0
IsEagerResolve returns true if the provider should be resolved at startup even when nothing else in the DI graph depends on it. Set by HookedSingleton.
func (Provider) IsExported ¶
IsExported returns true if the provider is exported to sibling modules. Exported providers are visible to modules that import the module that exports them.
func (Provider) IsTransient ¶
IsTransient returns true if the provider creates new instances per resolve.
type ProviderOption ¶ added in v0.5.0
type ProviderOption func(*Provider)
ProviderOption is a functional option for configuring providers.
func WithHooks ¶ added in v0.5.0
func WithHooks(hooks ...HookOption) ProviderOption
WithHooks attaches lifecycle hooks to a provider.
Example:
ligo.Factory[*Database](NewDatabase,
ligo.WithHooks(
ligo.OnInit(func(db *Database) error {
var err error
db.conn = sql.Open("postgres", "dsn")
return err
}),
ligo.BeforeShutdown(func(db *Database) error {
return db.conn.Close()
}),
),
)
type Registerable ¶ added in v0.5.0
type Registerable = lifecycle.Registerable
Registerable is the interface that services can implement to explicitly register their lifecycle hooks. This enables compile-time safety via method expressions instead of relying on duck typing.
Example:
type Database struct {}
func (d *Database) Connect() error { ... }
func (d *Database) Close() error { ... }
func (d *Database) Register(r *lifecycle.HookRegistry) {
r.OnInit(d.Connect) // Method expression - compile-time checked
r.OnShutdown(d.Close) // If Close doesn't exist → compile error
}
type RouteBuilder ¶
type RouteBuilder = http.RouteBuilder
RouteBuilder provides fluent API for composing routes with Guards, Pipes, Interceptors, and ExceptionFilters using the builder pattern.
type Router ¶
Router is the HTTP router interface that all router adapters must implement. It provides methods for registering routes, middleware, and managing the HTTP server.
type Throttler ¶ added in v0.11.0
Throttler is an in-memory rate limiter scoped to a single Ligo app.
func NewThrottler ¶ added in v0.11.0
NewThrottler returns an app-scoped Throttler. Caller is responsible for calling t.Close() on application shutdown to stop the cleanup goroutine.
t := ligo.NewThrottler(10, time.Minute)
defer t.Close()
cr.POST("", c.Create).Guard(t.Guard("ip"))