Class: ApiValve::Proxy

Inherits:
Object
  • Object
show all
Includes:
ActiveSupport::Callbacks
Defined in:
lib/api_valve/proxy.rb

Constant Summary collapse

FORWARDER_OPTIONS =
%w(endpoint request response permission_handler).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(forwarder) ⇒ Proxy

Returns a new instance of Proxy.



71
72
73
74
75
76
# File 'lib/api_valve/proxy.rb', line 71

def initialize(forwarder)
  @forwarder = forwarder
  @route_set = RouteSet.new
  @middleware = Middleware.new
  use Middleware::Router, route_set
end

Instance Attribute Details

#forwarder ⇒ Object (readonly)

Returns the value of attribute forwarder.



67
68
69
# File 'lib/api_valve/proxy.rb', line 67

def forwarder
  @forwarder
end

#middleware ⇒ Object (readonly)

Returns the value of attribute middleware.



67
68
69
# File 'lib/api_valve/proxy.rb', line 67

def middleware
  @middleware
end

#request ⇒ Object (readonly)

Returns the value of attribute request.



67
68
69
# File 'lib/api_valve/proxy.rb', line 67

def request
  @request
end

#route_set ⇒ Object (readonly) Also known as: router

Returns the value of attribute route_set.



67
68
69
# File 'lib/api_valve/proxy.rb', line 67

def route_set
  @route_set
end

Class Method Details

.build(config) ⇒ Object

Creates a n instance from a config hash and takes optional block which is executed in scope of the proxy



15
16
17
18
19
20
# File 'lib/api_valve/proxy.rb', line 15

def build(config)
  block = Proc.new if block_given? # capture the yield
  from_hash(config).tap do |proxy|
    proxy.instance_eval(&block) if block
  end
end

.from_config(file_name = nil) ⇒ Object



22
23
24
25
26
27
28
29
30
# File 'lib/api_valve/proxy.rb', line 22

def from_config(file_name = nil)
  file_name ||= name.underscore
  path = find_config(file_name)
  raise "Config not found for #{name.underscore}(.yml|.yml.erb) in #{ApiValve.config_paths.inspect}" unless path

  yaml = File.read(path)
  yaml = ERB.new(yaml, nil, '-').result if path.fnmatch? '*.erb'
  from_yaml yaml
end

.from_hash(config) ⇒ Object



36
37
38
39
40
41
42
43
# File 'lib/api_valve/proxy.rb', line 36

def from_hash(config)
  config = config.with_indifferent_access
  forwarder = Forwarder.new(forwarder_config(config))
  new(forwarder).tap do |proxy|
    Array.wrap(config[:use]).each { |mw| proxy.use mw }
    proxy.build_routes_from_config config[:routes]
  end
end

.from_yaml(string) ⇒ Object



32
33
34
# File 'lib/api_valve/proxy.rb', line 32

def from_yaml(string)
  from_hash YAML.load(string) # rubocop:disable Security/YAMLLoad
end

Instance Method Details

#build_routes_from_config(routes_config) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/api_valve/proxy.rb', line 87

def build_routes_from_config(routes_config)
  return forward_all unless routes_config

  routes_config.each do |route_config|
    method, path_regexp, request_override = *route_config.values_at('method', 'path', 'request')
    method ||= 'any' # no method defined means all methods
    if route_config['raise']
      deny method, path_regexp, with: route_config['raise']
    else
      forward method, path_regexp, request_override
    end
  end
end

#call(env) ⇒ Object



78
79
80
81
82
# File 'lib/api_valve/proxy.rb', line 78

def call(env)
  to_app.call(env)
rescue ApiValve::Error::Client, ApiValve::Error::Server => e
  render_error e
end

#deny(methods, path_regexp = nil, with: 'Error::Forbidden') ⇒ Object



115
116
117
118
119
# File 'lib/api_valve/proxy.rb', line 115

def deny(methods, path_regexp = nil, with: 'Error::Forbidden')
  Array.wrap(methods).each do |method|
    route_set.public_send(method, path_regexp, ->(*_args) { raise ApiValve.const_get(with) })
  end
end

#forward(methods, path_regexp = nil, request_override = {}) ⇒ Object



101
102
103
104
105
106
107
# File 'lib/api_valve/proxy.rb', line 101

def forward(methods, path_regexp = nil, request_override = {})
  Array.wrap(methods).each do |method|
    route_set.public_send(method, path_regexp, proc { |request, match_data|
      forwarder.call request, {'match_data' => match_data}.merge(request_override || {})
    })
  end
end

#forward_all ⇒ Object



109
110
111
112
113
# File 'lib/api_valve/proxy.rb', line 109

def forward_all
  route_set.any do |request, match_data|
    forwarder.call request, 'match_data' => match_data
  end
end