View Source Pluggable.StepBuilder (pluggable v1.0.1)
Conveniences for building pipelines.
defmodule MyApp do
use Pluggable.StepBuilder
step SomeLibrary.Logger
step :hello, upper: true
# A function from another module can be plugged too, provided it's
# imported into the current module first.
import AnotherModule, only: [interesting_step: 2]
step :interesting_step
def hello(token, opts) do
body = if opts[:upper], do: "WORLD", else: "world"
send_resp(token, 200, body)
end
end
Multiple steps can be defined with the step/2
macro, forming a pipeline.
The steps in the pipeline will be executed in the order they've been added
through the step/2
macro. In the example above, SomeLibrary.Logger
will
be called first and then the :hello
function step will be called on the
resulting token.
options
Options
When used, the following options are accepted by Pluggable.StepBuilder
:
:init_mode
- the environment to initialize the step's options, one of:compile
or:runtime
. Defaults:compile
.:log_on_halt
- accepts the level to log whenever the request is halted:copy_opts_to_assign
- anatom
representing an assign. When supplied, it will copy the options given to the Step initialization to the given token assign
step-behaviour
step behaviour
Internally, Pluggable.StepBuilder
implements the Pluggable
behaviour, which
means both the init/1
and call/2
functions are defined.
By implementing the Pluggable API, Pluggable.StepBuilder
guarantees this module
is a pluggable step and can be run via Pluggable.run/3
or used as part of
another pipeline.
overriding-the-default-pluggable-api-functions
Overriding the default Pluggable API functions
Both the init/1
and call/2
functions defined by Pluggable.StepBuilder
can
be manually overridden. For example, the init/1
function provided by
Pluggable.StepBuilder
returns the options that it receives as an argument, but
its behaviour can be customized:
defmodule StepWithCustomOptions do
use Pluggable.StepBuilder
step SomeLibrary.Logger
def init(opts) do
opts
end
end
The call/2
function that Pluggable.StepBuilder
provides is used internally to
execute all the steps listed using the step
macro, so overriding the
call/2
function generally implies using super
in order to still call the
step chain:
defmodule StepWithCustomCall do
use Pluggable.StepBuilder
step SomeLibrary.Logger
step SomeLibrary.AddMeta
def call(token, opts) do
token
|> super(opts) # calls SomeLibrary.Logger and SomeLibrary.AddMeta
|> assign(:called_all_steps, true)
end
end
halting-a-pluggable-step-pipeline
Halting a pluggable step pipeline
A pluggable step pipeline can be halted with Pluggable.Token.halt/1
. The builder
will prevent further steps downstream from being invoked and return the
current token. In the following example, the SomeLibrary.Logger
step never
gets called:
defmodule StepUsingHalt do
use Pluggable.StepBuilder
step :stopper
step SomeLibrary.Logger
def stopper(token, _opts) do
halt(token)
end
end
Link to this section Summary
Functions
Compiles a pluggable step pipeline.
A macro that stores a new step. opts
will be passed unchanged to the new
step.
Link to this section Types
Link to this section Functions
@spec compile(Macro.Env.t(), [{step(), Pluggable.opts(), Macro.t()}], Keyword.t()) :: {Macro.t(), Macro.t()}
Compiles a pluggable step pipeline.
Each element of the pluggable step pipeline (according to the type signature of this function) has the form:
{step_name, options, guards}
Note that this function expects a reversed pipeline (with the last step that has to be called coming first in the pipeline).
The function returns a tuple with the first element being a quoted reference to the token and the second element being the compiled quoted pipeline.
examples
Examples
Pluggable.StepBuilder.compile(env, [
{SomeLibrary.Logger, [], true}, # no guards, as added by the Pluggable.StepBuilder.step/2 macro
{SomeLibrary.AddMeta, [], quote(do: a when is_binary(a))}
], [])
A macro that stores a new step. opts
will be passed unchanged to the new
step.
This macro doesn't add any guards when adding the new step to the pipeline;
for more information about adding steps with guards see compile/3
.
examples
Examples
step SomeLibrary.Logger # step module
step :foo, some_options: true # step function