Routing subdomains to a slice

I’m building a multi-tenant app where users have their own space on a subdomain or possibly a custom domain name. The host option seems to be gone in Hanami 2.x. How can I route subdomains (*.mydomain.com) to a specific slice?

Hi @wout, thanks for using Hanami!

You’re right that we don’t have :host mounting support in 2.x yet. If you’re interested in contributing to Hanami, I’d love to see this come back, and would be very happy to support any work to do so. Here was where the feature introduced originally, if you’re looking for inspiration: Match against host by nicolaracco · Pull Request #104 · hanami/router · GitHub

In the meantime, you’d probably need to pursue alternative strategies. It might mean you have to reorient your routes around sub-paths for the time being.

2 Likes

Thanks for the quick reply!

I’m in for contributing, but I’m still getting to terms with Hanami, so I’ll need some pointers.

Is there a plan or idea of how this should work? Should it be the same approach as in version 1.3?

In my use case, I’ll need both subdomains and custom domains to be routed to a specific slice. So I imagine something like:

# the app's main root (fallback)
root to: 'home.show'

# tenant root, if conditions are met
slice :tenant, at: '/', if: ->(request) { ... } do
  root to: 'home.show'
end

The lambda (or callable object) returns a boolean and can contain arbitrary logic. So it can cover any use case ranging from specific subdomains (e.g. api.example.com) to wildcard subdomains, or even completely different domain names.

I’m not sure if this makes sense or is even achievable that way; just thinking out loud.

I would like to pick this up again as it’s one of the things I need the most myself to continue building, but I need some advice on the api.

The idea is to have an on option for slice blocks:

slice :admin, at: '/admin', on: { subdomain: 'app' } do
  get '/', to: 'home.index'
end

It reads naturally and gives us the of flexibility to match on different things, like a host for example:

slice :admin, at: '/admin', on: { host: 'other-host.com' } # ...

I’ve been familiarising myself with the code and trying a few things, but before I go too deep into the rabbit hole I’d like to get some feedback and suggestions. :slight_smile:

After further experimentation, I think this can also be handled at (base) action level within a slice. So if the admin slice is accessed on any other domain than app.example.com, just 404 or redirect elsewhere. And then do the same on base actions within other slices where such restrictions apply. This may be a good compromise to avoid adding the complexity of hosts and subdomains to the router.

To give some context, I started building a Rails app three months ago, and I’m now starting from over in Hanami. There will certainly be more things that don’t map one-to-one from Rails to Hanami.