A kick-ass HTTP router for use in Rack & Sinatra
Switch branches/tags
Nothing to show
Pull request Compare This branch is 439 commits behind joshbuddy:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


HTTP Router


When I wrote Usher, I made a few compromises in design that I wasn't totally happy with. More and more features got added to it, and eventually, it became harder to maintain. I took a few moments to work in Node.js, and wrote a router there called Sherpa, which I was happier with. But I felt that by losing more abstraction, and tackling just the problem of HTTP routing, I could come up with something even better.


This is very new code. Lots of stuff probably doesn't work right. I will likely never support all the features I had in Usher. Documentation is super-sparse.


  • Supports variables, and globbing.

  • Regex support for variables.

  • Request condition support.

  • Partial matches.

  • Supports interstitial variables (e.g. /my-:variable-brings.all.the.boys/yard).

  • Very fast and small code base (~600 loc).

  • Sinatra compatibility.



Takes the following options:

  • :default_app - The default #call made on non-matches. Defaults to a 404 generator.

  • :ignore_trailing_slash - Ignores the trailing slash when matching. Defaults to true.

  • :redirect_trailing_slash - Redirect on trailing slash matches to non-trailing slash paths. Defaults to false.

#add(name, options)

Maps a route. The format for variables in paths is:


Everything else is treated literally. Optional parts are surrounded by brackets. Partially matching paths have a trailing *. Optional trailing slash matching is done with /?.

Once you have a route object, use HttpRouter::Route#to to add a destination and HttpRouter::Route#name to name it.


r = HttpRouter.new
r.add('/test/:variable(.:format)').name(:my_test_path).to {|env| [200, {}, "Hey dude #{env['router.params'][:variable]}"]}

As well, you can support regex matching and request conditions. To add a regex match, use matching(:id => /\d+/). To match on a request condition you can use condition(:request_method => %w(POST HEAD)) or more succinctly request_method('POST', 'HEAD').

There are convenience methods HttpRouter#get, HttpRouter#post, etc for each request method.

Routes will not be recognized unless #to has been called on it.

#url(name or route, *args)

Generates a route. The args can either be a hash, a list, or a mix of both.

#call(env or Rack::Request)

Recognizes and dispatches the request.

#recognize(env or Rack::Request)

Only performs recognition.