Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for routing on subdomains #690

Open
AlecDivito opened this issue Aug 31, 2020 · 6 comments
Open

Add support for routing on subdomains #690

AlecDivito opened this issue Aug 31, 2020 · 6 comments

Comments

@AlecDivito
Copy link

Feature Request

Not all of the url routing is complete. I'm just wondering if support for routing on subdomains could be added into the framework.

Detailed Description

Add new methods to the router.rs and server.rs to support users to route on subdomains as well. An example of the resulting api I am thinking of would look like so:

let mut app = tide::new();
app.on_subdomain(":sub1.:sub2.:sub3").at("/").with(validate_subdomain).all(handle_user);

Context

I have an application that can have multiple tenets that can upload content to the server and would like to configure my webserver to be able to route on subdomains. This will benefit other users of tide who want to add the same functionality to their own application.

Possible Implementation

I haven't dove into the code base that much but i would assume that I would need to add functionality to server.rs and router.rs. I know this maybe a big addition so I wouldn't mind taking a chance and implementing it and putting in a PR.

Just wondering if this project is also interested in adding support for it and want to start a discussion.

@yoshuawuyts
Copy link
Member

We had a bit of a chat about this earlier today, I think this is a fairly promising direction. Earlier art for subdomain routing includes:

The Rails subrouting API seems quite interesting; if we were to translate that to Tide it could look like:

let mut app = tide::new();
app.subdomain("blog").at("/").get(|_| async { Ok("welcome to my blog") });
app.listen("localhost:8080").await?;

I'm leaning towards app.subdomain rather than abbreviating it as app.sub to prevent confusion with app.nest. Also we should only add subdomain to Server but not Route. Because subdomains feel like they should be declared at the root of the app, not nested within routes. As such we should perhaps also guard that when nesting apps we disallow subdomains on the app we're nesting.


That's my opinion, @jbr had some different ideas that I'm hoping he'll share!

@AlecDivito
Copy link
Author

AlecDivito commented Oct 1, 2020

Happy to hear the advice. I really enjoyed looking into the Rails subdomain routing and have an approach I think would work. I liked your proposal and I think the API design should look like the following:

let mut app = tide::new();
app.subdomain("example").at("/").get(|_| async { Ok("example subdomain") });
app.subdomain("portal").with(authentication).at("/").get(|_| async { Ok("Secure portal") });
app.subdomain(":user.blog").at("/").get(|req| async { Ok(req.param::<String>("user").unwrap()) });
app.listen("example.com").await?;

You may have noticed but I am making one prediction which is that the user treats their apex domain as their base url. I'm not sure 100% sure of a good way to allow the user to state the base url.

In terms of the design of additional code needed, I believe it would be best to do the same thing that route-recognizer is doing and by having a Router container around the Route struct. I propose wrapping a Subdomain struct around a Namespace container:

struct Server<State> {
    ...
    namespace: Namespace<State>;
    ...
}

struct Namespace<State> {
    router: SubdomainRouter<Subdomain<State>>
}

struct Subdomain<State> {
    subdomain: String,
    router: Router<State>,
    middleware: Vec<Arc<dyn Middleware<State>>>,
}

The SubdomainRouter<T> would just be like route-recognizer but dumber.

I wouldn't mind hearing your thoughts about this this design. I am working on an implementation and hopping for it to be finished soon.

@AlecDivito AlecDivito mentioned this issue Oct 9, 2020
8 tasks
@maxcountryman
Copy link

Is this still being considered? Would be nice to e.g. partition app routes from api routes.

@timtom-dev
Copy link

This is a feature that I'd really like as well. Any update on this? I'm willing to contribute if needed, I'll just need a little guidance.

@Fishrock123
Copy link
Member

I no longer recall the conversation well enough on what @jbr's ideas for this were, only that they were interesting.

@jbr
Copy link
Member

jbr commented May 10, 2022

I think I stalled out on that idea for tide because it would work better if there were a way to modularly experiment with alternative routers without having to opt everyone into a new experimental router. It might be worth exploring it in trillium first and then proposing it over here once the dust has settled, since adding a new router to trillium is just adding a new opt-in crate.

The core idea was to allow "route specifications" to look like a full url, with matchers in any position, so "https://$domain/users/$user_id" or ""$subdomain.example.com/users/$user_id" or "$scheme://example.com/users/$user_id" would all be valid route specs. Note that I typed this out with $ instead of : to represent named route params, in order to allow for $scheme://. It would still be valid to describe a route as "/users/$user_id", which would be functionally equivalent to "$scheme://$domain/users/$user_id" but without capturing scheme and domain (probably?).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants