Skip to content

[Routing] Add support for aliasing routes #38464

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

Merged
merged 1 commit into from
Nov 4, 2021
Merged

[Routing] Add support for aliasing routes #38464

merged 1 commit into from
Nov 4, 2021

Conversation

Lctrs
Copy link
Contributor

@Lctrs Lctrs commented Oct 7, 2020

Q A
Branch? 5.x
Bug fix? no
New feature? yes
Deprecations? yes
Tickets Fix #6088
License MIT
Doc PR None yet

Continuation of #38389

@Lctrs
Copy link
Contributor Author

Lctrs commented Oct 7, 2020

@stof Still WIP but I've made some changes to make deprecated aliases a thing as pointed out in #38389 (comment). WDYT ?

@nicolas-grekas nicolas-grekas added this to the 5.x milestone Oct 12, 2020
@Lctrs Lctrs changed the title [WIP][Routing] Add support for aliasing routes [Routing] Add support for aliasing routes Oct 23, 2020
@Lctrs
Copy link
Contributor Author

Lctrs commented Oct 23, 2020

Ready for review finally.

@Lctrs
Copy link
Contributor Author

Lctrs commented Dec 30, 2020

@jderusse I adressed all your comments except the ones where I left a comment indicating otherwise.

@haivala
Copy link

haivala commented Sep 21, 2021

Hope this gets merged!

@Lctrs
Copy link
Contributor Author

Lctrs commented Sep 21, 2021

I don't promise anything but I'll try to come back to this in the next weeks.

@Lctrs Lctrs marked this pull request as draft September 21, 2021 22:51
@Lctrs Lctrs marked this pull request as ready for review October 17, 2021 13:21
@Lctrs
Copy link
Contributor Author

Lctrs commented Oct 17, 2021

@jderusse @derrabus I have rebased the PR on top of 5.4 branch and adressed all your comments.

I tested this on a local test project and it worked as I would expect.

Do you have any more reviews to make ?

@Lctrs
Copy link
Contributor Author

Lctrs commented Oct 17, 2021

AppVeyor's failure is unrelated.

Copy link
Member

@jderusse jderusse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for moving this PR.
last few comment for my side.

Comment on lines 63 to 68
final public function alias(string $name, string $alias): AliasConfigurator
{
return new AliasConfigurator(
$this->collection->addAlias($name, $alias)
);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use the collection to build AliasConfigurator, I wonder if this method should'nt be part of CollectionConfigurator instead of RoutingConfigurator

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, from DX point of view, I would expect to be able to define alias directly from a RoutingConfigurator instance, to match DI's side.

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks really nice. Here are some nitpicking.


use Symfony\Component\Routing\Exception\InvalidArgumentException;

final class Alias
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should remove the final here

$this->id = $id;
}

public function redirect(string $id): self
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

withId could be less confusing, this doesn't redirect in the http meaning


/**
* Whether this alias is deprecated, that means it should not be referenced
* anymore.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be merged with the previous line

$this->deprecation = [
'package' => $package,
'version' => $version,
'message' => $message ?: 'The "%alias%" route alias is deprecated. You should stop using it, as it will be removed in the future.',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%alias_id%?


public function isDeprecated(): bool
{
return [] !== $this->deprecation;
Copy link
Member

@nicolas-grekas nicolas-grekas Nov 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return (bool) $this->deprecation; if we keep taking inspiration from Alias in DI

use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\Routing\Alias;

final class AliasConfigurator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should not be final

@@ -60,6 +60,13 @@ final public function collection(string $name = ''): CollectionConfigurator
return new CollectionConfigurator($this->collection, $name);
}

final public function alias(string $name, string $alias): AliasConfigurator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be on AddTrait?

/**
* @param array $config A resource config
* @param string $name The config key
* @param string $path The loaded file path
Copy link
Member

@nicolas-grekas nicolas-grekas Nov 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all 3 above lines could be removed imho

* @throws \InvalidArgumentException If one of the provided config keys is not supported,
* something is missing or the combination is nonsense
*/
private function validateAlias($config, string $name, string $path): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

array $config

}
$this->generator = new $this->options['generator_class']($routes, $this->context, $this->logger, $this->defaultLocale);
$this->generator = new $this->options['generator_class'](
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please keep this on one line


$deprecations[] = $deprecation;

trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed wrong. Dumping the URL generator should not trigger a deprecation. It should only be triggered when generating the url.
The only compile-time deprecation should be when a non-deprecated alias targets a deprecated one.

@Lctrs
Copy link
Contributor Author

Lctrs commented Nov 2, 2021

@nicolas-grekas @stof I believe I adressed all your comments.

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last round of review

@@ -116,6 +126,10 @@ public function all()
*/
public function get(string $name)
{
while ($this->hasAlias($name)) {
$name = $this->getAlias($name)->getId();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this loop detect circular refs + trigger a deprecation?
why do we need this logic btw? don't we always resolve the aliases before calling the method?
alternatively, shouldn't we move the logic in CompiledUrlGeneratorDumper and UrlGenerator here?

@@ -42,6 +43,13 @@ public function add(string $name, $path): RouteConfigurator
return new RouteConfigurator($this->collection, $route, $this->name, $parentConfigurator, $this->prefixes);
}

final public function alias(string $name, string $alias): AliasConfigurator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for final

@@ -42,6 +43,13 @@ public function add(string $name, $path): RouteConfigurator
return new RouteConfigurator($this->collection, $route, $this->name, $parentConfigurator, $this->prefixes);
}

final public function alias(string $name, string $alias): AliasConfigurator
{
return new AliasConfigurator(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be on one line

@@ -50,7 +50,11 @@ public function generate(string $name, array $parameters = [], int $referenceTyp
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
}

[$variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes] = $this->compiledRoutes[$name];
[$variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes, $deprecations] = $this->compiledRoutes[$name];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be safer to add + [6 => []] at the end of the expression in case the compiled routes come from a previous version of Routing. This might help with upgrading.

@Lctrs
Copy link
Contributor Author

Lctrs commented Nov 3, 2021

@nicolas-grekas all done.

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really cool :)

@@ -118,6 +129,24 @@ public function all()
*/
public function get(string $name)
{
$visited = [];
while (null !== $alias = $this->aliases[$name] ?? null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this loop from UrlGenerator to RouteCollection

return $this->aliases;
}

public function getAlias(string $name): ?Alias
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed hasAlias() and made getAlias() nullable instead, for consistency with get()

@nicolas-grekas
Copy link
Member

Thank you @Lctrs.

@nicolas-grekas nicolas-grekas merged commit 873e8ab into symfony:5.4 Nov 4, 2021
@Lctrs Lctrs deleted the feature/route-alias branch November 4, 2021 14:47
@Lctrs
Copy link
Contributor Author

Lctrs commented Nov 4, 2021

Thank you for taking care of the last polishing @nicolas-grekas

@matks
Copy link

matks commented Nov 16, 2021

Thank you for the great feature

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

Successfully merging this pull request may close these issues.

[Routing] Add support for alias routes
9 participants