Skip to content

Instantly share code, notes, and snippets.

@Sutto
Created November 26, 2012 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sutto/4148160 to your computer and use it in GitHub Desktop.
Save Sutto/4148160 to your computer and use it in GitHub Desktop.
Initial RocketPants 2.0 Version Recognition Thoughts
class VersionRecognizer
attr_reader :app, :matcher
def initialize(app, matcher)
@app = app
@matcher = compile_matcher(matcher)
end
def extract_version(env)
raise NotImplementedError, "You must use a subclass of VersionRecognizer that implements #extract_version(env)"
end
def call(env)
if versioned_env = extract_version(env)
env = env.merge(versioned_env)
end
app.call env
end
def version_additions(version)
version && {'rocket_pants.request_version' => version}
end
def compile_matcher(input)
if input.is_a?(String)
Regexp.new Regexp.escape(input.to_s).gsub /:version/, "(?<version>\d+)"
else
input
end
end
end
class ContentTypeRecognizer < VersionRecognizer
def extract_version(env)
content_type = env['HTTP_CONTENT_TYPE']
version = content_type[matcher, :version].try :to_i
version_additions version
end
end
class CustomHeaderRecognizer < VersionRecognizer
attr_reader :header, :header_key
def initialize(app, matcher = /(?<version>\d+)/, header = "X-API-Version")
super app, matcher
@header = header
@header_key = "HTTP_#{@header.to_s.gsub("-", "_").upcase}"
end
def extract_version(env)
header = env[header_key]
version = header.presence && header[matcher, :version].try(:to_i)
version_additions version
end
end
# Only path-based recognition can be used to generate routes.
# We need some way to declare this and map it.
class PathRecognizer < VersionRecognizer
attr_reader :path_regexp
def initialize(app, matcher = /(?:v?)(?<version>\d+)/)
super app, matcher
@path_regexp = /\A\/#{self.matcher}(?:\/|\Z)/
end
def extract_version(env)
version = env['PATH_INFO'].to_s[path_regexp, :version].try :to_i
version_additions version
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment