Mike Bailey

Rails Web API Versioning

| Comments

[2013-12-18 Why was so I attracted to the idea of versioning web APIs? I’ve never needed this.]

One way to make different versions of a web service available from the same webserver is to allow clients to prepend a version identifier to the URI path. There’s some discussion about the best way to use this but I like to default to no version identifier in URIs.

Passenger makes it easy to run different versions of your Rails web api alongside each other.

Update Your Webserver Config

Passenger allows you to direct traffic to different instances of your app. Here I’m serving brandish_v2 if no version identified is included in the URI.

<code># /etc/apache2/sites-available/brandish
<VirtualHost *:80>
  ServerName brandish.local
  CustomLog /var/log/apache2/brandish_access_log combined
  RackEnv development

  DocumentRoot /srv/brandish_v2/public
  RackBaseURI /v1
  RackBaseURI /v2
  <Directory /srv/brandish_v2/public/v1>   
    Options -MultiViews  
  <Directory /srv/brandish_v2/public/v2>   
    Options -MultiViews  

Symlink public/ into your DocumentRoot

This is the only tricky bit. Passenger expects the RackBaseURI’s you used in the web config to point at symlinks to the public/ directories of the different versions of your apps.

<code>ln -s /srv/brandish_v1/public -> /srv/brandish_v2/public/v1
ln -s /srv/brandish_v2/public -> /srv/brandish_v2/public/v2

Note Passenger was failing for me because it expected application.rb to be in controllers directory. I fixed it by creating a symlink from application_controller.rb to application.rb. I’m a bit confused as I thought that had been fixed in recent versions of Passenger. Maybe the RailsBaseURI code is not up to date.