Strategies
Flamigo includes a built-in strategy resolution system that helps you decouple and organize your API layer logic in a clean, modular, and reusable way.
A strategy in Flamigo is a named, callable function that encapsulates a specific piece of logic — typically used to handle external inputs such as API calls, WebSocket messages, or other interaction layers. Rather than binding behavior directly to a transport (like HTTP routes), Flamigo lets you define strategies under unique names and resolve them dynamically at runtime.
This design offers:
- A unified abstraction over different transport layers (HTTP, WebSocket, CLI, etc.)
- The ability to call strategies from anywhere — including other strategies or domain listeners
- A testable, reusable structure for external interfaces
- A generalized pattern that can be reused across different domains and contexts
Strategy Signatures
A strategy is simply a function that accepts a strategies.Context — an extended form of Flamigo’s context that includes additional request and response utilities.
type StrategyFunc func(ctx strategies.Context)Registering Strategies
Strategies are registered by name — usually in the internal/api/ layer — and grouped logically by application area or domain.
registry := strategies.NewRegistry("app")
registry.Register("app::domain:doSth", func(ctx strategies.Context) {
// Strategy logic here
})You can register multiple strategies under one registry, following a consistent naming convention (e.g. app::domain:action).
Strategy Context
The strategy context extends the base flamigo.Context, so it includes access to the current Actor. In addition, it provides structured access to the incoming request and the response.
type Request interface {
Action() string // The action name (e.g. app::domain:doSth)
Payload() any // The raw payload sent to the strategy
Bind(target any) error // Decode the payload (typically JSON) into a target struct
}
type Response interface {
SetResult(payload any) string // Sets the result to return from the strategy
SetError(err error) // Sets an error as the result
Result() any
Err() error
IsOk() bool
IsError() bool
}This setup provides everything your strategy needs to process input, work with actors, and respond in a consistent and structured way.
Calling Strategies
To call a strategy, you compose a strategy context with the appropriate flamingo.Context, action and payload, then invoke it through the registry:
registry := strategies.NewRegistry("app")
ctx := strategies.NewContext(flamigoCtx, "app::foo:bar", `{"foo": "bar"}`)
result := registry.Use(ctx)
if result.IsOk() {
// Handle success
}
// ...This approach enables strategies to be invoked internally — from domains, listeners, or even other strategies — without tightly coupling to the transport layer or request format.