Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
API version checking using Sinatra's before filter; supports nested resources
require 'sinatra'
# Set the version of the API being run here
#
MAJOR_VERSION = 1
MINOR_VERSION = 0
VERSION_REGEX = %r{/api/v(\d)\.(\d)}
helpers do
def version_compatible?(nums)
return MAJOR_VERSION == nums[0].to_i && MINOR_VERSION >= nums[1].to_i
end
end
# Enforce compatibility before the call. Rewrite the
# URL in the request to remove the API versioning stuff
#
before VERSION_REGEX do
if version_compatible?(params[:captures])
request.path_info = request.path_info.match(VERSION_REGEX).post_match
else
halt 400, "Version not compatible with this server"
end
end
before !VERSION_REGEX do
halt 404, "Resource not found"
end
# Reach this route using
# http://localhost:4567/api/vX.Y/hello
#
get '/hello' do
"Hello there, compatible client."
end
@edgarjs

This comment has been minimized.

Copy link

@edgarjs edgarjs commented Jul 1, 2012

Seems like I can skip the version validation by going to /hello directly. Since the before filter it's only ran for routes that matches the pattern, but /hello is still available directly.

There must be a way to "hide" the route.

@oisin

This comment has been minimized.

Copy link
Owner Author

@oisin oisin commented Jul 2, 2012

There is - I just put in another before handler, keyed to run when the regex doesn't match, and it appears to work for the oh, say, 45 seconds of manual checking I did :)

@edgarjs

This comment has been minimized.

Copy link

@edgarjs edgarjs commented Jul 2, 2012

Oh, it makes sense. That's nice, thanks.

@abunsenonesale

This comment has been minimized.

Copy link

@abunsenonesale abunsenonesale commented Jan 27, 2013

Question, how do you deal with code / responses that change between versions - it's not quite clear to me how to handle that scenario?

@oisin

This comment has been minimized.

Copy link
Owner Author

@oisin oisin commented Jan 28, 2013

If you are running multiple versions of your API, the important thing is to ensure that you segregate your code -- avoid having a situation where say a method does different things depending on which version of the API it is attending to. In a production environment I would run a couple of different servers and route to one or the other depending on the version of the API that is being requested.

Short summary - this Sinatra filtering will only work to verify what it's getting is version compatible, it won't solve the is issue of maintaining multiple API versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment