Define and execute callbacks with ease in Elixir
Add callbackex
to your list of dependencies in mix.exs
:
```elixir
# use the stable version
def deps do
[{:callbackex, "~> 0.1"}]
end
# use the latest version
def deps do
[{:callbackex, github: "secretworry/callbackex", branch: "master"}]
end
```
defmodule UserProcessor do
# Use Callbackex
use Callbackex, :before_create, :after_create
# Define callbacks
callbacks do
before_create :check_ip
before_create User.ValidateName, limit: 10
after_create Indexer, index: :user
after_create AuditLog, operation: :create
end
# Use callbacks
def create(params) do
with {:ok, params} <- invoke_callback(:before_create, params),
{:ok, user} <- do_create_user(params),
{:ok, user} <- invoke_callback(:after_create, user) do
{:ok, user}
end
end
end
Callbackex
supports two kinds of callback: function callback and module callback
A function callback receives a value and a set of options as arguments and returns next value
def check_title(params, %{limit: 10}) do
if params["title"] |> String.length > 10 do
{:error, "Illegal title"}
else
{:ok, params}
end
end
A module callback provides an init/1
function to initialize options and implements the call/2
function, receiving the
value to process and the initialized options, and returning the value for further processing
defmodule IndexCallback do
def init(opts), do: %{index: Keyword.fetch!(opts, :index), type: Keyword.fetch!(opts, :type)}
def call(model, %{index: index, type: type}) do
# I'm working on the ElasticSearch wrapper called Elaxto :)
Elaxto.index(type, model) |> Exlato.run(index: index)
end
end
To define callbacks for your module:
-
use Callbackex
in your module and provide callback names as opts. For example, I want to define callbacksbefore_create
,after_create
in myPostProcessor
elixir defmodule PostProcessor do use Callbackex, ~w{before_create after_create}a end
-
Define a
callbacks
block in your module with the macrocallbacks
. In the macro you can define your callbacks in the following format:callback_name calback_fun_or_module [callback_opts]
For example, to add a callback to check params before creating post, and to index post after creating:
callbacks do before_create :check_params, title: %{max_length: 10} after_create IndexCallback, index: :post_index, type: :post end
-
After defined all the callbacks, now you can use the
invoke_callback(callback_name, value)
in the methods of module defining theCallbackex
def create(params) do with {:ok, params} <- invoke_callback(:before_create, params), {:ok, post} <- do_creat_post(params), {:ok, post} <- invoke_callback(:after_create, params), do: {:ok, post} end
Callbackex source code is released under Apache 2 License. Check LICENSE file for more information.