Skip to content

Instantly share code, notes, and snippets.

@oisin
Forked from leereilly/gist:987094
Created May 23, 2011 18:34
Show Gist options
  • Save oisin/987247 to your computer and use it in GitHub Desktop.
Save oisin/987247 to your computer and use it in GitHub Desktop.
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
Copy link

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
Copy link
Author

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
Copy link

edgarjs commented Jul 2, 2012

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

@abunsenonesale
Copy link

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
Copy link
Author

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