Class: WebPipe::Pipe
- Inherits:
-
Object
- Object
- WebPipe::Pipe
- Defined in:
- lib/web_pipe/pipe.rb
Overview
Composable rack application builder.
An instance of this class helps build rack applications that can compose. Besides the DSL, which only adds a convenience layer, this is the higher abstraction on the library.
Applications are built by plugging functions that take and return a Conn instance. That's an immutable struct that contains all the request information alongside methods to build the response. See #plug for details.
Middlewares can also be added to the resulting application thanks to #use.
Be aware that instances of this class are immutable, so methods return new objects every time.
The instance itself is the final rack application.
config.ru
require 'web_pipe/pipe'
app = WebPipe::Pipe.new .use(:runtime, Rack::Runtime) .plug(:content_type) do |conn| conn.add_response_header('Content-Type', 'text/plain') end .plug(:render) do |conn| conn.set_response_body('Hello, World!') end
run app
Constant Summary collapse
- EMPTY_CONTAINER =
Container that resolves nothing
{}.freeze
- EMPTY_PLUGS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
[].freeze
- EMPTY_MIDDLEWARE_SPECIFICATIONS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
[].freeze
- Container =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Types.Interface(:[])
Instance Attribute Summary collapse
-
#container ⇒ Object
readonly
Returns the value of attribute container.
-
#context ⇒ Object
readonly
Returns the value of attribute context.
- #middleware_specifications ⇒ Object readonly private
- #plugs ⇒ Object readonly private
Instance Method Summary collapse
- #call(env) ⇒ Object private
- #compose(name, spec) ⇒ Object
-
#initialize(container: EMPTY_CONTAINER, context: nil, plugs: EMPTY_PLUGS, middleware_specifications: EMPTY_MIDDLEWARE_SPECIFICATIONS) ⇒ Pipe
constructor
(see #plug).
- #inject(plugs: {}, middleware_specifications: {}) ⇒ Object private
-
#middlewares ⇒ Hash{Symbol=>Array<WebPipe::RackSupport::Middleware>}
Middlewares #used in the app, mapped by their names.
-
#operations ⇒ Hash{Symbol => Proc}
Operations #plugged to the app, mapped by their names.
-
#plug(name, spec = nil) {|| ... } ⇒ WebPipe::Pipe
Names and adds a plug operation to the application.
- #to_middlewares ⇒ Object private
- #to_proc ⇒ Object private
-
#use(name, *spec) ⇒ WebPipe::Pipe
Names and adds a rack middleware to the final application.
Constructor Details
#initialize(container: EMPTY_CONTAINER, context: nil, plugs: EMPTY_PLUGS, middleware_specifications: EMPTY_MIDDLEWARE_SPECIFICATIONS) ⇒ Pipe
74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/web_pipe/pipe.rb', line 74 def initialize( container: EMPTY_CONTAINER, context: nil, plugs: EMPTY_PLUGS, middleware_specifications: EMPTY_MIDDLEWARE_SPECIFICATIONS ) @plugs = plugs @middleware_specifications = middleware_specifications @container = Container[container] @context = context end |
Instance Attribute Details
#container ⇒ Object (readonly)
Returns the value of attribute container.
49 50 51 |
# File 'lib/web_pipe/pipe.rb', line 49 def container @container end |
#context ⇒ Object (readonly)
Returns the value of attribute context.
53 54 55 |
# File 'lib/web_pipe/pipe.rb', line 53 def context @context end |
#middleware_specifications ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
68 69 70 |
# File 'lib/web_pipe/pipe.rb', line 68 def middleware_specifications @middleware_specifications end |
#plugs ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
65 66 67 |
# File 'lib/web_pipe/pipe.rb', line 65 def plugs @plugs end |
Instance Method Details
#call(env) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
202 203 204 |
# File 'lib/web_pipe/pipe.rb', line 202 def call(env) rack_app.call(env) end |
#compose(name, spec) ⇒ Object
149 150 151 152 |
# File 'lib/web_pipe/pipe.rb', line 149 def compose(name, spec) use(name, spec) .plug(name, spec) end |
#inject(plugs: {}, middleware_specifications: {}) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/web_pipe/pipe.rb', line 188 def inject(plugs: {}, middleware_specifications: {}) res_mw_specs = RackSupport::MiddlewareSpecification.inject( self.middleware_specifications, middleware_specifications ) res_plugs = Plug.inject( self.plugs, plugs ) with( plugs: res_plugs, middleware_specifications: res_mw_specs ) end |
#middlewares ⇒ Hash{Symbol=>Array<WebPipe::RackSupport::Middleware>}
Middlewares #used in the app, mapped by their names.
Returns them wrapped within RackSupport::Middleware instances, from where you can access their classes and options.
169 170 171 172 173 |
# File 'lib/web_pipe/pipe.rb', line 169 def middlewares @middlewares ||= Hash[ middleware_specifications.map { |mw_spec| [mw_spec.name, mw_spec.call] } ] end |
#operations ⇒ Hash{Symbol => Proc}
Operations #plugged to the app, mapped by their names.
157 158 159 160 161 |
# File 'lib/web_pipe/pipe.rb', line 157 def operations @operations ||= Hash[ plugs.map { |plug| [plug.name, plug.call(container, context)] } ] end |
#plug(name, spec = nil) {|| ... } ⇒ WebPipe::Pipe
Names and adds a plug operation to the application.
The operation can be provided in several ways:
- Through the
spec
parameter as:- Anything responding to
#call
(like a Proc). - As a string or symbol key for something registered in #container.
- Anything responding to
#to_proc
(like another WebPipe::Pipe instance or an instance of a class including WebPipe). - As
nil
(default), meaning that the operation is a method in #context matching thename
parameter.
- Anything responding to
- Through a block, if the
spec
parameter isnil
.
104 105 106 107 108 109 110 111 |
# File 'lib/web_pipe/pipe.rb', line 104 def plug(name, spec = nil, &block_spec) with( plugs: [ *plugs, Plug.new(name: name, spec: spec || block_spec) ] ) end |
#to_middlewares ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
183 184 185 |
# File 'lib/web_pipe/pipe.rb', line 183 def to_middlewares middlewares.values.flatten end |
#to_proc ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
176 177 178 179 180 |
# File 'lib/web_pipe/pipe.rb', line 176 def to_proc ConnSupport::Composition .new(operations.values) .method(:call) end |
#use(name, middleware_class) ⇒ WebPipe::Pipe #use(name, middleware_class, middleware_options) ⇒ WebPipe::Pipe #use(name, to_middlewares) ⇒ WebPipe::Pipe
Names and adds a rack middleware to the final application.
The middleware can be given in three forms:
- As one or two arguments, the first one being a rack middleware class, and optionally a second one with its initialization options.
- As something responding to
#to_middlewares
with an array of RackSupport::Middleware (like another WebPipe::Pipe instance or a class including WebPipe), case in which all middlewares are used.
136 137 138 139 140 141 142 143 |
# File 'lib/web_pipe/pipe.rb', line 136 def use(name, *spec) with( middleware_specifications: [ *middleware_specifications, RackSupport::MiddlewareSpecification.new(name: name, spec: spec) ] ) end |