Module: Pancake::Middleware

Included in:
Pancake, Stack
Defined in:
lib/pancake/middleware.rb

Overview

Provides a mixin to use on any class to give it middleware management capabilities. This module provides a rich featureset for defining a middleware stack.

Middlware can be set before, or after other middleware, can be tagged / named, and can be declared to only be active in certain types of stacks.

Defined Under Namespace

Classes: StackMiddleware

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.build(app, mwares) ⇒ Object

Build a middleware stack given an application and some middleware classes

StackMiddleware instances where each instance

defines a middleware to use in constructing the stack

Examples:

Pancake::Middleware.build(@app, [MWare_1, MWare_2])

Parameters:

  • app (Object)

    a rack application to wrap in the middlware list

  • mwares (Array<StackMiddleware>)

    an array of

Returns:

  • (Object)

    An application instance of the first middleware defined in the array The application should be an instance that conforms to Rack specifications

Author:

  • Daniel Neighman

Since:

  • 0.1.0



42
43
44
45
46
# File 'lib/pancake/middleware.rb', line 42

def self.build(app, mwares)
  mwares.reverse.inject(app) do |a, m|
    m.middleware.new(a, *m.args, &m.block)
  end
end

.extended(base) ⇒ Object

When extending a base class with the Pancake::Middleware, an inner class StackMiddleware is setup on the base class. This inner class is where all the inforamation is stored on the stack to be defined The inner StackMiddleware class is also set to be inherited with the base class (and all children classes) So that each class gets its own copy and may maintain the base stack from the parent, but edit it in the child.



16
17
18
19
20
21
22
23
24
# File 'lib/pancake/middleware.rb', line 16

def self.extended(base)
  base.class_eval <<-RUBY
    class StackMiddleware < Pancake::Middleware::StackMiddleware; end
  RUBY
  if base.is_a?(Class)
    base.inheritable_inner_classes :StackMiddleware
  end
  super
end

Instance Method Details

#middlewaresArray<StackMiddleware>

Returns An array of middleware specifications in the order they should be used to wrap the application.

Parameters:

  • labels (Array<Symbol>)

    An array of labels specifying the stack labels to use to build the middlware list

Returns:

  • (Array<StackMiddleware>)

    An array of middleware specifications in the order they should be used to wrap the application

See Also:

Author:

  • Daniel Neighman

Since:

  • 0.1.0



57
58
59
# File 'lib/pancake/middleware.rb', line 57

def middlewares
  self::StackMiddleware.middlewares
end

#stack(name = nil, opts = {}) ⇒ Object

Useful for adding additional information into your middleware stack definition

This middleware will be named MyMiddleware, and can be specified with (:before | :after) => MyMiddleware

This middleware will be named :foo and can be specified with (:before | :after) => :foo

This middleware will be named :foo and will be run before the middleware named :bar If :bar is not run, :foo will not be run either

This middleware will be named :foo and will be run after the middleware named :bar If :bar is not run, :foo will not be run either

Examples:

Declaring un-named middleware via the stack

MyClass.stack.use(MyMiddleware)

Declaring a named middleware via the stack

MyClass.stack(:foo).use(MyMiddleware)

Declaring a named middleware with a :before key

MyClass.stack(:foo, :before => :bar).use(MyMiddleware)

Declaring a named middlware with an :after key

MyClass.stack(:foo, :after => :bar).use(MyMiddleware)

Parameters:

  • name (Object) (defaults to: nil)

    The name of a given middleware. Each piece of middleware has a name in the stack. By naming middleware we can refer to it later, swap it out for a different class or even just remove it from the stack.

  • opts (Hash) (defaults to: {})

    An options hash

Options Hash (opts):

  • :before (Object)

    Sets this middlware to be run after the middleware named. Name is either the name given to the middleware stack, or the Middleware class itself.

  • :after (Object)

    Sets this middleware to be run after the middleware name. Name is either the name given to the middleware stack or the Middleware class itself.

See Also:

Author:

  • Daniel Neighman

Since:

  • 0.1.0



100
101
102
103
104
105
106
107
108
109
# File 'lib/pancake/middleware.rb', line 100

def stack(name = nil, opts = {})
  if self::StackMiddleware._mwares[name] && mw = self::StackMiddleware._mwares[name]
    unless mw.stack == self
      mw = self::StackMiddleware._mwares[name] = self::StackMiddleware._mwares[name].dup
    end
    mw
  else
    self::StackMiddleware.new(name, self, opts)
  end
end

#use(middleware, *_args) { ... } ⇒ Object

Adds middleware to the current stack definition

Examples:

Bare use call

MyApp.use(MyMiddleware, :some => :option){ # middleware initialization block here }

Use call after a stack call

MyApp.stack(:foo).use(MyMiddleware, :some => :option){ # middleware initialization block here }

Parameters:

  • middleware (Class)

    The middleware class to use in the stack

  • opts (Hash)

    An options hash that is passed through to the middleware when it is instantiated

Yields:

  • The block is provided to the middlewares #new method when it is initialized

See Also:

Author:

  • Daniel Neighman

Since:

  • 0.1.0



128
129
130
# File 'lib/pancake/middleware.rb', line 128

def use(middleware, *_args, &block)
  stack(middleware).use(middleware, *_args, &block)
end