Serving RESTful URLs with mod_rewrite

We’ve been experimenting with an internal API to our app to facilitate development of UI tests by our QA team.  After much discussion (likely to described in a blog post some time down the line), the decision was made to provide the API in a RESTful style over HTTPS.  Rather than make a separate PHP script at each location an API request could possibly land, it made more sense to have all requests routed to a single handler that delegated the requests to the appropriate class.  Doing this in Apache required a little configuration and research.

Apache provides a module for rewriting incoming URLs, thus giving us the ability to route all requests for the API to the PHP handler.  Configuring this required a simple regular expression.

RewriteRule ^/api.*$ /api/handler.php [L]

That was simple enough.  No more information is required in the URL by the handler, it has access to the originally requested resource through $_SERVER['REQUEST_URI'].  This now means that a request to /api/team/1, would be actually be sent to /api/handler.php, which would then determine that a request for the details of the team with id 1 should be processed.

You may have noticed something odd about the rewrite above: there is no query string.  Indeed, the query string is not specified and that is wrong.  Two things are at play here, (1) RewriteRule does not match against any text in the query string, and (2) the substitution URL completely rewrites the URL, so the original query string is not magically carried over. This is simultaneously useful and troublesome. The mod_rewrite module provides several directives for working with the URL, one of which is named RewriteCond, which, in addition to the URL itself, lets you match against several of the other HTTP things going on (aka Server Variables).  One of these is the query string.  Matching against the query string (or anything for that matter) in a RewriteCond gives you access to back reference those matches in an ensuing RewriteRule directive using the %n syntax in addition the canonical $n syntax of the regular expression used for RewriteRule.

As useful as this is, in our situation we want to maintain the entire query string, which did not require use of the RewriteCond directive at all.  We accomplish this by,

RewriteRule ^/api.*$ /api/handler.php?%{QUERY_STRING} [L]

For full details of the mod_rewrite module, check out the doc, http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html.  The list of Server Variables available for substitution can be found in the discussion of the RewriteCond directive.  For some examples of the RewriteCond directive, check out: http://fantomaster.com/faarticles/rewritingurls.txt.

  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Twitter
  • Google Bookmarks
  • DZone
  • HackerNews
  • LinkedIn
  • Reddit
  • Phillip Brown

    Thank you, the %{QUERY_STRING} helped me with my RESTful URLs.

  • Chris

    I know this is an old post but you could also use the QSA flag to append the query string to the end of the re-written URL.