Class: Hanami::Slice::Routing::Middleware::Stack Private

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/hanami/slice/routing/middleware/stack.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Wraps a rack app with a middleware stack

We use this class to add middlewares to the rack application generated from Hanami::Slice::Router.

“‘ stack = Hanami::Slice::Routing::Middleware::Stack.new stack.use(Rack::ContentType, “text/html”) stack.to_rack_app(a_rack_app) “`

Middlewares can be mounted on specific paths:

“‘ stack.with(“/api”) do

stack.use(Rack::ContentType, "application/json")

end “‘

See Also:

Since:

  • 2.0.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStack

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.

Returns a new instance of Stack.

Since:

  • 2.0.0



57
58
59
60
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 57

def initialize
  @stack = Hash.new { |hash, key| hash[key] = [] }
  @namespaces = [Hanami::Middleware]
end

Instance Attribute Details

#namespacesArray<Object> (readonly)

Returns an array of Ruby namespaces from which to load middleware classes specified by symbol names given to #use.

Defaults to ‘[Hanami::Middleware]`.

Returns:

  • (Array<Object>)

Since:

  • 2.0.0



53
54
55
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 53

def namespaces
  @namespaces
end

#stackObject (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.

Since:

  • 2.0.0



42
43
44
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 42

def stack
  @stack
end

Instance Method Details

#each(&blk) ⇒ 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.

Since:

  • 2.0.0



147
148
149
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 147

def each(&blk)
  @stack.each(&blk)
end

#empty?Boolean

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.

Returns:

  • (Boolean)

Since:

  • 2.0.0



141
142
143
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 141

def empty?
  @stack.empty?
end

#initialize_copy(source) ⇒ 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.

Since:

  • 2.0.0



64
65
66
67
68
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 64

def initialize_copy(source)
  super
  @stack = stack.dup
  @namespaces = namespaces.dup
end

#mapped(builder, prefix, &blk) ⇒ 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.

Since:

  • 2.0.0



153
154
155
156
157
158
159
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 153

def mapped(builder, prefix, &blk)
  if prefix == ::Hanami::Router::DEFAULT_PREFIX
    builder.instance_eval(&blk)
  else
    builder.map(prefix, &blk)
  end
end

#to_hashObject

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.

Since:

  • 2.0.0



133
134
135
136
137
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 133

def to_hash
  @stack.each_with_object({}) do |(path, _), result|
    result[path] = stack_for(path)
  end
end

#to_rack_app(app) ⇒ 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.

Since:

  • 2.0.0



120
121
122
123
124
125
126
127
128
129
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 120

def to_rack_app(app)
  unless Hanami.bundled?("rack")
    raise "Add \"rack\" to your `Gemfile` to run Hanami as a rack app"
  end

  mapping = to_hash
  return app if mapping.empty?

  Hanami::Middleware::App.new(app, mapping)
end

#update(other) ⇒ 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.

Since:

  • 2.0.0



111
112
113
114
115
116
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 111

def update(other)
  other.stack.each do |path_prefix, items|
    stack[path_prefix].concat(items)
  end
  self
end

#use(spec, *args, path_prefix: ::Hanami::Router::DEFAULT_PREFIX, before: nil, after: nil, **kwargs, &blk) ⇒ self

Adds a middleware to the stack.

Examples:

# Using a symbol name; adds Hanami::Middleware::BodyParser.new([:json])
middleware.use :body_parser, :json

# Using a class name
middleware.use MyMiddleware

# Adding a middleware before or after others
middleware.use MyMiddleware, before: SomeMiddleware
middleware.use MyMiddleware, after: OtherMiddleware

Parameters:

  • spec (Symbol, Class)

    the middleware name or class name

  • args (Array, nil)

    Arguments to pass to the middleware’s ‘.new` method

  • before (Class, nil) (defaults to: nil)

    an optional (already added) middleware class to add the middleware before

  • after (Class, nil) (defaults to: nil)

    an optional (already added) middleware class to add the middleware after

Returns:

  • (self)

Since:

  • 2.0.0



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/hanami/slice/routing/middleware/stack.rb', line 94

def use(spec, *args, path_prefix: ::Hanami::Router::DEFAULT_PREFIX, before: nil, after: nil, **kwargs, &blk)
  middleware = resolve_middleware_class(spec)
  item = [middleware, args, kwargs, blk]

  if before
    @stack[path_prefix].insert((idx = index_of(before, path_prefix)).zero? ? 0 : idx - 1, item)
  elsif after
    @stack[path_prefix].insert(index_of(after, path_prefix) + 1, item)
  else
    @stack[path_prefix].push(item)
  end

  self
end