A Specification Pattern implementation in Elixir.
Using brex you can easily
- define
- compose and
- evaluate
business rules to dynamically drive the flow of your application.
Brex was built to allow you to define and compose rules to evaluate them later. This enables you to build your rules from some kind of configuration, be it a database, a CSV or JSON or anything else.
Maybe you want to allow your customer to create dynamic rules for sending out emails or push notifications? Or you want to decide on the type of event to trigger based on incoming data? Or you think bigger and want to create some kind of flow chart interface?
Whatever your particular use-case, Brex has you covered when it comes to composition of rules.
The lowest building stone of Brex is a rule. A rule can have many shapes, for example this is a rule:
&is_list/1This is a rule too:
Brex.all([&is_list/1, &(length(&1) > 0)])Or this:
defmodule MyRule do
@behaviour Brex.Rule
@impl true
def evaluate(:foo), do: true
def evaluate(:bar), do: false
endAlso this:
defmodule MyStruct do
use Brex.Rule.Struct
defstruct [:foo]
def evaluate(%{foo: foo}, value) do
foo == value
end
endWell great that you ask, that's simple too!
iex> Brex.satisfies? MyRule, :foo
trueAs you can see, Brex is flexible and easy to use. All of this is based on the Brex.Rule.Evaluable protocol, if you're really interested, take a look at Brex.Rule which talks about the possible rule types a little bit more.
Also, as you might have noticed, I used an all/1 function in the examples
above. This is the compose part of Brex: it allows you to link rules
using boolean logic.
It currently supports:
allanynone
I think the names speak for themself.
You can define your own operators, if you're interested then take a look at the Brex.Operator module.
Simply add brex to your list of dependencies in your mix.exs:
def deps do
[
{:brex, "~> 0.1.0"}
]
endRight now, there is no need for any kind of configuration in Brex. In case you see some need for it, please open an issue.