Skip to content

Instantly share code, notes, and snippets.

@Antiarchitect
Last active August 29, 2015 14:02
Show Gist options
  • Save Antiarchitect/dd3677aa36c017feac94 to your computer and use it in GitHub Desktop.
Save Antiarchitect/dd3677aa36c017feac94 to your computer and use it in GitHub Desktop.
Api Compatibility Check
class ApiCompatibilityChecker
class CheckApiCompatibilityError < StandardError; end
SERVER_API_VERSION = '1.0.0'
VERSION_REGEXP = /\A(?<major>\d{1,5})\.(?<minor>\d{1,5})\.(?<patch>\d{1,5})\z/
attr_reader :request, :env
def initialize(request)
@request = request
@env = request.env
end
def check!
client_api_version = request.params[:client_api_version]
return true unless client_api_version
result = VERSION_REGEXP.match(client_api_version) rescue nil
client_major = Integer(result[:major]) rescue nil
server_major = Integer(VERSION_REGEXP.match(SERVER_API_VERSION)[:major])
ApiV2::CompatibilityCheckerController.action(:invalid_client_version_format).call(env) and return unless client_major
return true unless server_major != client_major
env['client_api_version'] = client_api_version
ApiV2::CompatibilityCheckerController.action(:client_needs_to_be_upgraded).call(env) and return if client_major < server_major
ApiV2::CompatibilityCheckerController.action(:server_needs_to_be_upgraded).call(env) and return if server_major < client_major
raise CheckApiCompatibilityError
end
end
module ApiV2
class CompatibilityCheckerController < BaseController
SERVER_API_VERSION = ApiCompatibilityChecker::SERVER_API_VERSION
def invalid_client_version_format
respond_with ({ errors: [{error: 'Invalid client version format.'}],
server_api_version: SERVER_API_VERSION }),
status: :bad_request, root: 'api_compatibility_check'
end
def client_needs_to_be_upgraded
respond_with ({ errors: [{error: 'Client needs to be upgraded.'}],
server_api_version: SERVER_API_VERSION, client_api_version: env['client_api_version'] }),
status: :bad_request, root: 'api_compatibility_check'
end
def server_needs_to_be_upgraded
respond_with ({ errors: [{error: 'Server needs to be upgraded.'}],
server_api_version: SERVER_API_VERSION, client_api_version: env['client_api_version'] }),
status: :internal_server_error, root: 'api_compatibility_check'
end
end
end
# ...
api_compatibility_check = lambda { |request| ApiCompatibilityChecker.new(request).check! }
# ...
scope constraints: api_compatibility_check do
# Here be API routes
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment