class Phenotype::Versioner
Attributes
env[R]
routes[R]
strategies[R]
versions[R]
Public Class Methods
new(routes: {}, strategies: [], env: {})
click to toggle source
# File lib/phenotype/versioner.rb, line 9 def initialize(routes: {}, strategies: [], env: {}) @routes = routes @versions = routes.keys.sort.reverse @strategies = strategies @env = env end
Public Instance Methods
call()
click to toggle source
# File lib/phenotype/versioner.rb, line 16 def call # rubocop:disable Metrics/AbcSize return display_errors if errors? cascading_versions.each do |v| if strategies.first.instance_of?(PathStrategy) && version_mismatch?(v) env['PATH_INFO'] = updated_versioned_path(env['PATH_INFO'], v) end route = call_route(v) handler = ResponseHandler.new(route.block.call(env)) return handler.response unless route.cascade? && handler.retry? end end
Private Instance Methods
call_route(version)
click to toggle source
# File lib/phenotype/versioner.rb, line 83 def call_route(version) routes.fetch( version, version_not_found_response("Unable to satisfy request for Version: #{current_version}") ) end
cascading_versions()
click to toggle source
# File lib/phenotype/versioner.rb, line 67 def cascading_versions @cascading_versions ||= versions.select { |el| el <= current_version } end
current_version()
click to toggle source
# File lib/phenotype/versioner.rb, line 63 def current_version @current_version ||= strategies.detect { |strat| strat.version(env) }.version(env).to_i end
default_response(status_code, message = '')
click to toggle source
# File lib/phenotype/versioner.rb, line 90 def default_response(status_code, message = '') proc { [status_code, { 'Content-Type' => 'text/html' }, [message]] } end
display_errors()
click to toggle source
# File lib/phenotype/versioner.rb, line 49 def display_errors return no_strategy_response.call(env) if strategies.empty? return too_many_strategies_response.call(env) if too_many_strategies? return version_not_found_response.call(env) unless supported_version? end
errors?()
click to toggle source
# File lib/phenotype/versioner.rb, line 45 def errors? strategies.empty? || too_many_strategies? || !supported_version? end
no_strategy_response()
click to toggle source
# File lib/phenotype/versioner.rb, line 71 def no_strategy_response @no_strategy_response ||= default_response(406, 'No Strategies provided') end
path_version()
click to toggle source
# File lib/phenotype/versioner.rb, line 35 def path_version path = Rack::Request.new(env).path match = path.match(strategies.first.version_pattern) match&.captures&.first end
supported_version?()
click to toggle source
# File lib/phenotype/versioner.rb, line 59 def supported_version? @supported_version ||= versions.include?(current_version) end
too_many_strategies?()
click to toggle source
# File lib/phenotype/versioner.rb, line 55 def too_many_strategies? @too_many_strategies ||= strategies.size > 1 end
too_many_strategies_response()
click to toggle source
# File lib/phenotype/versioner.rb, line 75 def too_many_strategies_response @too_many_strategies_response ||= default_response(400, 'Too mant strategies provided, Supports only one') end
updated_versioned_path(path, version)
click to toggle source
# File lib/phenotype/versioner.rb, line 41 def updated_versioned_path(path, version) path.sub(path_version, version.to_s) end
version_mismatch?(version)
click to toggle source
# File lib/phenotype/versioner.rb, line 31 def version_mismatch?(version) path_version && (path_version != version.to_s) end
version_not_found_response(message = "Version:
click to toggle source
# File lib/phenotype/versioner.rb, line 79 def version_not_found_response(message = "Version: #{current_version} is not found") default_response(406, message) end