-
-
Save oisin/987247 to your computer and use it in GitHub Desktop.
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 |
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 :)
Oh, it makes sense. That's nice, thanks.
Question, how do you deal with code / responses that change between versions - it's not quite clear to me how to handle that scenario?
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.
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.