Class: Bandiera::Middleware

Inherits:
Object
  • Object
show all
Defined in:
lib/bandiera/middleware.rb

Overview

Rack middleware for talking to a Bandiera feature flagging service.

The benefit of using this middleware is two-fold when working with a Bandiera server:

  1. Performance - Using this middleware, you will only call the Bandiera server once per-request (in contrast to using the ‘enabled?` method where you will make one request per-use).

  2. Better Quality Code - If you use the more advanced features in Bandiera (user groups and percentages) you will no longer need to pass around user objects and UUIDs in your code. This does assume the use of other middlewares to supply user objects and UUIDs though.

This middleware can be used in conjunction with the Macmillan::Utils::Middleware::Uuid (or one of your own design) to automatically generate UUIDs for your users. See github.com/springernature/bandiera/wiki for more information on this approach.

Since:

  • 3.0.0

Instance Method Summary collapse

Constructor Details

#initialize(app, opts = {}) ⇒ Middleware

Builds a new instance of Bandiera::Middleware

Parameters:

  • app

    The rack application

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

    Additional options for the middleware

Options Hash (opts):

  • :client (Bandiera::Client)

    The Bandiera::Client class to use

  • :groups (Array) — default: []

    The feature flag groups to request and store in the rack env

  • :uuid_env_key (String) — default: Macmillan::Utils::Middleware::Uuid.env_key

    The rack env key containing a UUID for your current user (to pass to ‘user_id` in Bandiera)

  • :user_env_key (String) — default: 'current_user'

    The rack env key containing your currently logged in user

  • :user_group_method (Symbol) — default: :email

    The method to call on the current user to pass to ‘user_group` in Bandiera

See Also:

  • Client
  • Macmillan::Utils::Middleware::Uuid

Since:

  • 3.0.0



31
32
33
34
35
36
37
38
39
40
# File 'lib/bandiera/middleware.rb', line 31

def initialize(app, opts = {})
  @app               = app
  @client            = opts[:client]
  @groups            = opts[:groups] || []
  @uuid_env_key      = opts[:uuid_env_key] || Macmillan::Utils::Middleware::Uuid.env_key
  @user_env_key      = opts[:user_env_key] || 'current_user'
  @user_group_method = opts[:user_group_method] || :email

  fail ArgumentError, 'You must supply a Bandiera::Client' unless @client
end

Instance Method Details

#call(env) ⇒ Object

Since:

  • 3.0.0



42
43
44
# File 'lib/bandiera/middleware.rb', line 42

def call(env)
  dup.process(env)
end

#process(env) ⇒ Object

Since:

  • 3.0.0



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/bandiera/middleware.rb', line 46

def process(env)
  request = Rack::Request.new(env)

  user       = request.env[@user_env_key]
  user_group = user ? user.public_send(@user_group_method) : nil
  uuid       = request.env[@uuid_env_key]

  if @groups.empty?
    @client.get_all(user_group: user_group, user_id: uuid).each do |group, flags|
      request.env["bandiera.#{group}"] = flags
    end
  else
    @groups.each do |group|
      request.env["bandiera.#{group}"] = @client.get_features_for_group(group, user_group: user_group, user_id: uuid)
    end
  end

  @app.call(request.env)
end