Skip to content
Define and execute callbacks with ease in Elixir
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
lib
test
.gitignore
LICENSE
README.md
mix.exs
mix.lock

README.md

Callbackex

Define and execute callbacks with ease in Elixir

Installation

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
```

Quick Example

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

Callbacks

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

Usage

To define callbacks for your module:

  1. use Callbackex in your module and provide callback names as opts. For example, I want to define callbacks before_create, after_create in my PostProcessor elixir defmodule PostProcessor do use Callbackex, ~w{before_create after_create}a end

  2. Define a callbacks block in your module with the macro callbacks. 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
  3. After defined all the callbacks, now you can use the invoke_callback(callback_name, value) in the methods of module defining the Callbackex

    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

License

Callbackex source code is released under Apache 2 License. Check LICENSE file for more information.

You can’t perform that action at this time.