20

Say I have:

require 'sinatra'

get '/' { "hi" }
get '/a' { "a" }
get '/b' { "b" }

Is there any easy to way obtain a list of all defined routes in my Sinatra application?

I investigated Sinatra::Base.routes, but that doesn't appear to contain the routes I just defined.

I was hoping to have a nice way to make a self documenting API like routes.each { |r| p r } to get:

/
/a
/b
tester
  • 22,441
  • 25
  • 88
  • 128

2 Answers2

33

You should investigate Sinatra::Application.routes, which contains your routes. This prints the regular expressions of your route patterns:

require 'sinatra'

get '/'  do "root" end
get '/a' do "a" end
get '/b' do "b" end

Sinatra::Application.routes["GET"].each do |route|
  puts route[0]
end

To make things simpler, take look at the sinatra-advanced-routes extension. It gives you a nice API for introspecting the routes:

require 'sinatra'
require 'sinatra/advanced_routes'

get '/'  do "root" end
get '/a' do "a" end
get '/b' do "b" end

Sinatra::Application.each_route do |route|
  puts route.verb + " " + route.path
end

See the README of sinatra-advanced-routes for more documentation and examples.

Miikka
  • 4,573
  • 34
  • 47
  • Thanks! That explains Sinatra::Application.instance_variables part where I get @routes from it. There is also [:@conditions, :@routes, :@filters, :@errors, :@middleware, :@prototype, :@extensions, :@templates] although I have yet to understand how to use these as well. Perhaps should I ask as a question? – Douglas G. Allen Aug 29 '15 at 23:07
4

Here's a rake task to output a list of routes:

desc 'List defined routes'
task :routes do
  require 'app/web/web'

  Shoebox::Server.routes.map do |method, routes|
    routes.map { |r| r.first.to_s }.map do |route|
      "#{method.rjust(7, ' ')} #{route}"
    end
  end.flatten.sort.each do |route|
    puts route
  end
end

Output:

    GET /asset/:id
   HEAD /asset/:id
   POST /asset/:aggregate_id/provide
OPTIONS /asset
twe4ked
  • 2,832
  • 21
  • 24