destroytoday.com

Subdomain routing in Sinatra

Cushion serves the web app from the my. subdomain and the signup routes from the get. subdomain. I’ve always relied on Sinatra::Namespace to scope the routes, so the root path (/) under get.cushionapp.com would go to the right place, while the root path under my.cushionapp.com would go to its right place. I recently discovered that Sinatra has been cascading through the modular apps for these routes and triggering the 404 route for each modular app that shares the same route you’re visiting. Not great, and explains why Cushion’s route requests have felt slower than they should be. While I do use Sinatra::Router to mount all the modular apps, I didn’t realize it supports custom conditionals. With this ability, I was able to refactor the subdomain scoping with a custom conditional method, subdomain, that checks the subdomain of the request. Instead of using:

namespace host_name: /^get./ do
  mount MyApp
end

...I mount the modular app inside a subdomain block, like this:

subdomain :get do
  mount MyApp
end