Modware
Modware is a library for using middleware (pipeline) patterns in Ruby projects. It features a simple interface and supports "callback" style semantics in the middleware stack, including before, after, and around methods.
Installation
As usual:
gem 'modware' # in a Gemfile
spec.add_dependency 'modware' # in a .gemspec
Usage
Creating a stack
Create a stack using:
stack = Modware::Stack.new(env: klass)
where klass is a Class for the environment instance that will be passed to the layers of the stack. As a shorthand for the common case, you can simply pass an array of keys, e.g.
stack = Modware::Stack.new(env: [:name, :options, :results])
and Modware will define a class that accepts those keys as keyword arguments, and has accessor methods for each (see
KeyStruct).
Defining middleware
Middleware is defined as a module that defines one or more middleware methods:
module MyMiddleware
# define any of these as needed...
def before(env)
# code to be called before the base implementation
end
def after(env)
# code to be called after the base implementation
end
def around(env)
# setup/wrapper code
yield env # continues execution down the stack
# cleanup code
end
def implement(env)
# completely replaces the base implementation or any earlier middleware's implement()
end
end
The module may use instance variables and define other methods as needed (e.g. to abide by Metz' rule #2).
To add the middleware to a stack:
stack.add(MyMiddleware)
Middleware is always added to the end of the stack.
Executing a stack
To execute a stack do:
stack.start(*args) { |env|
# base implementation
}
The execution sequence of the stack is as follows:
- Create environment instance
env = env_klass.new(*args) - Call each middleware
before(env)method, in the order they were added - Call each middleware
around(env)method, in the order they were added. This bottoms out with the lastimplement(env)method to be added, if any, otherwise the base implementation - Call each middleware
after(env)method, in the order they were added - Return
env
Helpers
Modware.is_middleware?(mod)returns truthy ifmod's instance methods include any of the middleware methods:before,:after,:around, or:implement
See also
The middleware gem works well, following a rack-like execution model.
Contributing
Contributions welcome -- feel free to open issues or submit pull requests. Thanks!