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

[Routing] Add support for alias routes #6088

Closed
hason opened this issue Nov 22, 2012 · 52 comments · Fixed by #38464
Closed

[Routing] Add support for alias routes #6088

hason opened this issue Nov 22, 2012 · 52 comments · Fixed by #38464

Comments

@hason
Copy link
Contributor

hason commented Nov 22, 2012

# routes.yml

app_index:
    pattern: /

vendor_bundle_index:
    alias: app_index
@stof
Copy link
Member

stof commented Nov 22, 2012

This would only be useful for the generator, right ?

@hason
Copy link
Contributor Author

hason commented Nov 22, 2012

Precisely.

@Baachi
Copy link
Contributor

Baachi commented Nov 22, 2012

👍

@Tobion
Copy link
Member

Tobion commented Jan 8, 2013

So it's only useful when you want to use a vendor route under a different name. Don't think it's such a good practice.

@fabpot
Copy link
Member

fabpot commented Jan 12, 2013

I'm also -1 on this feature. Bundles should choose unique and comprehensive names for their routes.

@hfietz
Copy link

hfietz commented Jun 5, 2013

+1

I think this would be a useful feature for routes that might be implemented by different vendor bundles, when you also want to have templates that are agnostic of that. Sort of extending the idea of service interfaces to routing / templating.

My specific usecase was the "login" route, i. e., I wanted to use a route name of "login" in templates, which would render to a path of "/login", but behind that could be things like the "fos_user_security_login" route from the FOSUserBundle, or something else. I don't think knowing who will display the login form is the responsibility of the templates.

@Syam
Copy link

Syam commented Jun 25, 2013

A "forward" parameter would be better :

app_index:
    pattern: /
    forward: vendor_bundle_index

Bundles should not care of App configuration, but App should care of Bundles.

@hice3000
Copy link
Contributor

👍

@aurelijusrozenas
Copy link
Contributor

+1
what hfietz said.

@sergio-toro
Copy link

+1

@sstok
Copy link
Contributor

sstok commented Oct 11, 2013

I can see an advantage in this, but aliasing is just one thing.

Being able to set a parent so you can reuse the definition and overwrite them (like with DI services).
Using it as an alias is then just one thing.

@gondo
Copy link
Contributor

gondo commented Jan 27, 2014

this would be useful f.e. in fos_user bundle:

fos_user_profile:
    resource: custom_alias

or is there any other way how to do this?

@ftassi
Copy link

ftassi commented Feb 24, 2014

I'm 👍 for this. I have in mind the same exact use case that @hfietz exposed. I want my application to be decoupled from 3d bundles routes names. FOSUserBundle makes a great example imho, I want my application to use a "register" route, and then, If I decide to use FOSUserBundle, I want to alias that to fos_user_registration_register to my "register" route

@gggeek
Copy link

gggeek commented Mar 16, 2014

I'm not sure if this is considered a good practice, but what about having 2 routes for the same functionality, where the difference is the authentication set up? so one route could be protected by basic auth and one by session. (ideally the same route should be just accessible using both authentication methods, but other open issues make me think this is currently impossible)

@cordoval
Copy link
Contributor

I am 👎 this is not the real problem. The problem seems to be we want to customize the FOSUser Bundle behavior. In that light the statement from @fabpot

Bundles should choose unique and comprehensive names for their routes.

passes the problem to FOSUB

@gggeek
Copy link

gggeek commented Mar 17, 2014

@cordoval what do you mean the problem is with fosuserbundle? I do not even use it. I exposed a different usecase which leads to the same need... ftassi above also described a different reason for the same need

@stof
Copy link
Member

stof commented Mar 17, 2014

Bundles should choose unique and comprehensive names for their routes.

passes the problem to FOSUB

@cordoval FOSUserBundle uses a unique name. The issue here is that people seem to want to make the FOSUserBundle redirection point to their own route (btw, FOSUserBundle even allows to customize the redirection, so we cannot be blamed for this)

@Tobion
Copy link
Member

Tobion commented Mar 17, 2014

All they want is to use their own route names because naming is the hardest thing. But it's neither needed nor really useful.

@gondo
Copy link
Contributor

gondo commented Mar 17, 2014

@stof how can i customize fos_user_profile redirection?

@fabpot
Copy link
Member

fabpot commented Apr 28, 2014

Closing this feature request for the reasons explained by @Tobion and myself.

@fabpot fabpot closed this as completed Apr 28, 2014
@fazy
Copy link

fazy commented Nov 11, 2014

Edit: I've posted a new issue #12472 instead.

Here is a possible use case, please feel free to point out an alternative approach though. In short, I want to be able to do something like this in Twig:

{{ path('contact') }}

and get the right route depending on the current hostname (but other applications might have other criteria).

Let's say I have English and German versions of a site, under different domains: example.co.uk and example.de. Then, I can import groups of routes like this:

uk_routes:
    resource: @MyBundle/Resources/config/routing_uk.yml
    host: "example.co.uk"

de_routes:
    resource: @MyBundle/Resources/config/routing_de.yml
    host: "example.de"

Then, in each file, I might try something like this:

# routing_uk.yml
contact:
    path: /contact
    defaults:
        _controller: my_site.controller.default:contactAction

# routing_de.yml
contact:
    path: /kontakt
    defaults:
        _controller: my_site.controller.default:contactAction

But... this won't work, because one "contact" route silently overwrite the other.

An "alias" (or "forward") parameter would help here:

# routing_uk.yml
uk_contact:
    alias: contact
    path: /contact
    defaults:
        _controller: my_site.controller.default:contactAction
    options:
        foo: bar_uk_example

# routing_de.yml
de_contact:
    alias: contact
    path: /uber_uns
    defaults:
        _controller: my_site.controller.default:contactAction
    options:
        foo: bar_de_example

If only one route had the "contact" alias, it's easy for the Generator to know which route to use (we could even just duplicate the route behind the scenes, to save a copy and paste).

But here, the routing generator is faced with two different routes with the same alias. So it needs to decide which one to pick. In this case, I want it to filter on the host (each route has this, but I defined it at the file level instead of each route). Maybe there are other things to filter on too, so it should be configurable/extensible.

For now, I have created a very basic route generator that does this. It's part of a very rough/experimental bundle that should probably be split apart, but hopefully it gives an idea.

Of course, I could be looking at this the wrong way. Maybe we don't need route aliases, but namespaces? Or multiple routers (but then, how to select which one is being used?)

I also started a mailing list topic about this. I'm interested to know the best approach, how other people satisfy this use case, and whether a future Symfony route generator can allow allow multiple route candidates (aliases, or similar).

@stof
Copy link
Member

stof commented Nov 23, 2014

@fazy your use case is not what is requested in this issue

@aistis-
Copy link

aistis- commented Sep 15, 2015

What if you have a generated internal name like vendorName_node_generated_internal_root_categoryOne_subCategory and want create alias like:

app_catalog_subCategory:
    alias: vendorName_node_generated_internal_root_categoryOne_subCategory

I would love to have this feature too.

@paceto256
Copy link

1+

@Masadow
Copy link

Masadow commented Feb 2, 2016

Have another use case:

I have a multi page component. When i refer to it in my views, I'd like to have a route that points to the index of that component.

However this component is just a set of pages so I have mycomponent_pagename, mycomponent_otherpagenameand so on.

If I later want to change the entry point of that component (to go let's from mycomponent_pagename to mycomponent_otherpagename, I will actually need to change in my twig every occurences of mycomponent_pagenamewhich is a pain and can easily leads to mistakes.

What would be great instead would be to define a mycomponent_index that is just an alias of mycomponent_pagename so I will be able to change it easily and quickly later.

@dave-newson
Copy link

I have another variant use for this feature. We're refactoring some legacy application code and want to do two things:

  1. Provide a new name for the existing routes, to better suite our internal route naming guidelines going forward.
  2. Alias the old route, so we don't have to hunt down and change the referenced in our legacy code.

The only way we can see to do this right now is double up on our route definitions, which is ugly.

I understand the objection to the original use case, but is there a compelling reason why Services can be aliased but Routes cannot?

@matks
Copy link

matks commented Feb 7, 2019

A deprecation feature for routes would also be a very useful feature.

However in a usecase where the only thing we want to change is the route name because it is not accurate / relevant anymore (and we are multiple people with this usecase 😄 ) that would mean we will define in a routing YAML file both the old and new route version with same path, same controller, same requirements, same ... everything.

I'm not sure how the router handles 2 identical routes (to match request with controller), except the names, being declared 🤔 but anyway this means to duplicate a lot of YAML statements.

@gingerCodeNinja
Copy link

We need the aliases for the ability to deprecate routes. In our case, we're not changing the URL, just changing the route name itself, as per reasons mentioned above. So we can't throw a deprecation error just because someone hit a perfectly valid URL.

This is a similar feature to Command name's having aliases. They're a great way to deprecate one name whilst switching to the new name.

@nicolas-grekas
Copy link
Member

Aliases feel like over-engineering at this stage to me: we need a way to deprecate routes for sure. Being able to deduplicate them using aliases is a secondary goal that will create additional complexity we'd better not deal with (yet) IMHO.

@matks
Copy link

matks commented Feb 7, 2019

Thank you for your answer :) I'll make a PR for the deprecation feature.

For the aliases, I guess I'll make a workaround. I'm thinking about creating dummy routes with the old route names and hijacking $router->generate($routeName) so that when $routeName is one of the deprecated route names it actually replaces $routeName with the right one and keep going on. But this fake Route will be quite unusable else.

@PierreRambaud
Copy link

What behavior do you want with a deprecated feature?
You can't add a message when you use $router->generate($routeName) in href or in a redirect.

So, instead of having

# routes.yml
app_index:
  pattern: /

vendor_bundle_index:
  alias: app_index

It should maybe better to have?

# routes.yml
app_index:
  pattern: /
  deprecate: vendor_bundle_index

WDYT?

@teohhanhui
Copy link
Contributor

teohhanhui commented Apr 17, 2019

I'm working on migrating https://github.com/Sylius/ShopApiPlugin to API Platform, and here's our use case:

Sample output from bin/console debug:router:

  api_register_customer_requests_post_collection                             POST             ANY      ANY    /shop-api/{channelCode}/register                                               
  sylius_shop_api_register                                                   POST             ANY      ANY    /shop-api/{channelCode}/register

Being able to alias sylius_shop_api_register to api_register_customer_requests_post_collection would be perfect.

Without route aliases, if we want to keep the old route name (for BC with clients that use route names), we are forced to manually declare the above route for API Platform, instead of letting API Platform auto generate it.

@stof
Copy link
Member

stof commented Apr 17, 2019

@nicolas-grekas the difference between (deprecated) aliases and creating a second deprecated routes is that aliases would be available only during URL generation, but would not impact the matcher. Creating a second deprecated route with the same pattern would impact the matcher (and may have weird effects in it)

@stof
Copy link
Member

stof commented Apr 17, 2019

We have 2 entry points for the routing component: matching and url generation. We need to evaluate how each use case would happen:

  • what would a deprecated route mean for URL matching ? We cannot trigger deprecations in the client sending us the HTTP request. I'm not sure what deprecating a route should mean for the matching
  • for URL generation, I see 2 separate use cases:
    • renaming routes, deprecating the old name. For that, an alias feature would be much better than forcing to declare a second deprecated route for which you need to keep the whole config in sync; and it would avoid confusing the matching with 2 identical routes.
    • deprecating the URL entirely. This relates to what such a deprecated route would mean during matching, as it is the url-generation side of the deprecated endpoint case of the matching.

@nicolas-grekas
Copy link
Member

Deprecation aliases for the generator make sense to me too. For the matcher I don't know what they would mean. Note that I also don't know how the configuration for this could look like - in a non-ambiguous way. PR welcome I suppose.

@stof
Copy link
Member

stof commented Apr 18, 2019

that's why I think we need aliases (maybe only deprecation aliases), and not deprecated routes by themselves. So I will re-open this issue.

@stof stof reopened this Apr 18, 2019
@matks
Copy link

matks commented Apr 18, 2019

Deprecation aliases for the generator make sense to me too. For the matcher I don't know what they would mean. Note that I also don't know how the configuration for this could look like - in a non-ambiguous way. PR welcome I suppose.

I confirm my usecase is for the generator, and can be solved by either aliases or (even better) deprecation aliases.

Configuration for aliases could be as as simple as:

admin_metas_listing:
  path: /metas
  alias: admin_metas_index
  methods: GET
  defaults:
    _controller: 'AppBundle:Admin\Configure\ShopParameters\Meta:index'

So admin_metas_listing and admin_metas_index would both be valid route names, that can be used to generated the same URL.

Configuration for deprecation aliases might be similar:

admin_metas_listing:
  path: /metas
  deprecated: admin_metas_index
  methods: GET
  defaults:
    _controller: 'AppBundle:Admin\Configure\ShopParameters\Meta:index'

or more complex, but looking better:

admin_metas_index:
  deprecated: true
  replacement: admin_metas_listing

admin_metas_listing:
  path: /metas
  methods: GET
  defaults:
    _controller: 'AppBundle:Admin\Configure\ShopParameters\Meta:index'

For the behavior: admin_metas_listing and admin_metas_index would both be valid route names, that can be used to generated the same URL. However using deprecated admin_metas_index would result in a deprecation notice in logs. This would do the job 👍

@gingerCodeNinja
Copy link

gingerCodeNinja commented Apr 18, 2019

Those suggestions look good to me 👍

I think the first deprecated alias solution is better, as it doesn't require you to modify the deprecated route definition directly, which might be out of the control of the person deprecating it (in a large organisation, like our case, it might be another bundle/repo handled by another team); maybe change deprecated: admin_metas_index to replaces: ['admin_metas_index'] so it can deprecate/replace multiple. However, either solution is perfectly fine.

@Lctrs
Copy link
Contributor

Lctrs commented Oct 2, 2020

First implementation attempt is here : #38389 for anyone interested to review it.

@carsonbot
Copy link

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?

@matks
Copy link

matks commented Apr 5, 2021

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?

Yes 😊

@carsonbot carsonbot removed the Stalled label Apr 5, 2021
@PierreRambaud
Copy link

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?

Yep! 😅

@carsonbot
Copy link

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?

@PierreRambaud
Copy link

Thank you for this suggestion. There has not been a lot of activity here for a while. Would you still like to see this feature?

Yes ❤️

@carsonbot carsonbot removed the Stalled label Oct 7, 2021
@Tobion
Copy link
Member

Tobion commented Oct 7, 2021

I'm closing the issue. There is already an open PR. If you feel strongly about this feature, you can help make the PR move forward. Thanks.

@Tobion Tobion closed this as completed Oct 7, 2021
nicolas-grekas added a commit that referenced this issue Nov 4, 2021
This PR was merged into the 5.4 branch.

Discussion
----------

[Routing] Add support for aliasing routes

| Q             | A
| ------------- | ---
| Branch?       | 5.x
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | yes
| Tickets       | Fix #6088 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License       | MIT
| Doc PR        | None yet

Continuation of #38389

Commits
-------

43575a1 [Routing] Add support for aliasing routes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.