View Source Jido.Action behaviour (Jido v1.0.0)
Defines a discrete, composable unit of functionality within the Jido system.
Each Action represents a delayed computation that can be composed with others to build complex workflows and workflows. Actions are defined at compile-time and provide a consistent interface for validating inputs, executing workflows, and handling results.
Features
- Compile-time configuration validation
- Runtime input parameter validation
- Consistent error handling and formatting
- Extensible lifecycle hooks
- JSON serialization support
Usage
To define a new Action, use the Jido.Action
behavior in your module:
defmodule MyAction do
use Jido.Action,
name: "my_action",
description: "Performs a specific workflow",
category: "processing",
tags: ["example", "demo"],
vsn: "1.0.0",
schema: [
input: [type: :string, required: true]
]
@impl true
def run(params, _context) do
# Your action logic here
{:ok, %{result: String.upcase(params.input)}}
end
end
Callbacks
Implementing modules must define the following callback:
run/2
: Executes the main logic of the Action.
Optional callbacks for custom behavior:
on_before_validate_params/1
: Called before parameter validation.on_after_validate_params/1
: Called after parameter validation.on_after_run/1
: Called after the Action's main logic has executed.
Error Handling
Actions use the OK
monad for consistent error handling. Errors are wrapped
in Jido.Error
structs for uniform error reporting across the system.
Parameter Validation
Note on Validation: The validation process for Actions is intentionally open. Only fields specified in the schema are validated. Unspecified fields are not validated, allowing for easier Action composition. This approach enables Actions to accept and pass along additional parameters that may be required by other Actions in a chain without causing validation errors.
Summary
Callbacks
Called after the Action's main logic has executed.
Called after parameter validation.
Called before parameter validation.
Handles errors and performs compensation when enabled.
Executes the Action with the given parameters and context.
Functions
Defines a new Action module.
Raises an error indicating that Actions cannot be defined at runtime.
Types
Callbacks
Called after the Action's main logic has executed.
This optional callback allows for post-processing of the Action's result before it is returned to the caller.
Parameters
result
: The result map returned by therun/2
function.
Returns
{:ok, modified_result}
wheremodified_result
is a potentially modified result map.{:error, reason}
if post-processing fails.
Called after parameter validation.
This optional callback allows for post-processing of validated parameters
before they are passed to the run/2
function.
Parameters
params
: A map of validated input parameters.
Returns
{:ok, modified_params}
wheremodified_params
is a map of potentially modified parameters.{:error, reason}
if post-processing fails.
Called before parameter validation.
This optional callback allows for pre-processing of input parameters before they are validated against the Action's schema.
Parameters
params
: A map of raw input parameters.
Returns
{:ok, modified_params}
wheremodified_params
is a map of potentially modified parameters.{:error, reason}
if pre-processing fails.
@callback on_error( failed_params :: map(), error :: Jido.Error.t(), context :: map(), opts :: keyword() ) :: {:ok, map()} | {:error, Jido.Error.t()}
Handles errors and performs compensation when enabled.
Called when an error occurs during Action execution if compensation is enabled in the Action's configuration.
Parameters
failed_params
: The parameters that were passed to the failed executionerror
: The Error struct describing what went wrongcontext
: The execution context at the time of failureopts
: Additional options for compensation handling
Returns
{:ok, result}
if compensation succeeded{:error, reason}
if compensation failed
Examples
def on_error(params, error, context, opts) do
# Perform compensation logic
case rollback_changes(params) do
:ok -> {:ok, %{compensated: true, original_error: error}}
{:error, reason} -> {:error, "Compensation failed: #{reason}"}
end
end
Executes the Action with the given parameters and context.
This callback must be implemented by modules using Jido.Action
.
Parameters
params
: A map of validated input parameters.context
: A map containing any additional context for the workflow.
Returns
{:ok, result}
whereresult
is a map containing the workflow's output.{:error, reason}
wherereason
describes why the workflow failed.
Functions
Defines a new Action module.
This macro sets up the necessary structure and callbacks for a Action, including configuration validation and default implementations.
Options
:name
- Required. The name of the Action. Must contain only letters, numbers, and underscores.:description
(String.t/0
) - A description of what the Action does.:category
(String.t/0
) - The category of the Action.:tags
(list ofString.t/0
) - A list of tags associated with the Action. The default value is[]
.:vsn
(String.t/0
) - The version of the Action.:compensation
(keyword/0
) - The default value is[]
.:enabled
(boolean/0
) - The default value isfalse
.:max_retries
(non_neg_integer/0
) - The default value is1
.:timeout
(non_neg_integer/0
) - The default value is5000
.
:schema
(keyword/0
) - A NimbleOptions schema for validating the Action's input parameters. The default value is[]
.
Examples
defmodule MyAction do
use Jido.Action,
name: "my_action",
description: "Performs a specific workflow",
schema: [
input: [type: :string, required: true]
]
@impl true
def run(params, _context) do
{:ok, %{result: String.upcase(params.input)}}
end
end
@spec new() :: {:error, Jido.Error.t()}
Raises an error indicating that Actions cannot be defined at runtime.
This function exists to prevent misuse of the Action system, as Actions are designed to be defined at compile-time only.
Returns
Always returns {:error, reason}
where reason
is a config error.
Examples
iex> Jido.Action.new()
{:error, %Jido.Error{type: :config_error, message: "Actions should not be defined at runtime"}}
@spec new(map() | keyword()) :: {:error, Jido.Error.t()}