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

[RFC][Routing] Added the Route attribute #37474

Merged
merged 1 commit into from
Sep 7, 2020

Conversation

derrabus
Copy link
Member

@derrabus derrabus commented Jul 1, 2020

Q A
Branch? 5.2
Bug fix? no
New feature? yes
Deprecations? no
Tickets N/A
License MIT
Doc PR symfony/symfony-docs#14230

I was wondering if we can make use of attributes as a replacement for Doctrine Annotations for configuring routes.

I have modified the existing AnnotationClassLoader so that it merges attributes and annotations. This way, an application could transparently switch from annotations to attributes. Moreover, the AnnotationClassLoader does not require an annotation reader anymore.

Since the chosen syntax #[…] is treated as a comment by php 7, I was able to use the existing annotation class, which makes the migration even easier.

Example with Doctrine Annotations

use Symfony\Component\Routing\Annotation\Route;

class ActionPathController
{
    /**
     * @Route("/path", name: "action")
     */
    public function action()
    {
    }
}

Same example with the proposed Attribute

use Symfony\Component\Routing\Annotation\Route;

class ActionPathController
{
    #[Route('/path', name: 'action')]
    public function action()
    {
    }
}

@carsonbot carsonbot added Status: Needs Review RFC RFC = Request For Comments (proposals about features that you want to be discussed) Routing Feature labels Jul 1, 2020
Copy link
Contributor

@ro0NL ro0NL left a comment

Choose a reason for hiding this comment

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

i like it :)

should we offer hybrid support by default? Thus vendor controllers could specify both attributes as well as annotations. Not sure this makes sense in practice though, otherwise i'd expect an exception if attributes and annotations are mixed&matched.
edit: nevermind, this works as expected already.

we could use sibling/nested attributes for rich options perhaps. Not sure it works out.

@derrabus
Copy link
Member Author

derrabus commented Jul 1, 2020

Right now, you can mix&match attributes and annotations. It would have the same effect as if you specified multiple annotations. This was the easiest way to implement it, but this behavior is certainly debatable.

@derrabus derrabus force-pushed the improvement/route-attributes branch from c23533f to 513cc5c Compare July 1, 2020 18:53
@ro0NL
Copy link
Contributor

ro0NL commented Jul 1, 2020

i think it's fair to assume both definitions remain equivalent. Then it works on all SF versions, loading either one or another.

I was wondering if we can make use of attributes as a replacement for Doctrine Annotations

raising the bigger question, is there any reason not to? Should we deprecate annotation support once we support php:^8?

@javiereguiluz
Copy link
Member

Please note that the attribute syntax has just changed from << ... >> to @@... See https://wiki.php.net/rfc/shorter_attribute_syntax

@derrabus
Copy link
Member Author

derrabus commented Jul 2, 2020

@javiereguiluz This has not been merged yet, has it?

@javiereguiluz
Copy link
Member

Not merged yet ... but approved, so it will be merged "soon" (I was notified about this by this nice @beberlei service: https://php-rfc-watch.beberlei.de/)

@derrabus
Copy link
Member Author

derrabus commented Jul 2, 2020

All right. If I changed the PR now, Travis won't be able to run my tests anymore. I don't expect the reflection API to be affected by the change, so all I will need to do is adjust the test fixtures and the attribute class itself to the new syntax. I'll do this as soon as Travis' nightly build supports it.

@nicolas-grekas nicolas-grekas added this to the next milestone Jul 3, 2020
@derrabus
Copy link
Member Author

derrabus commented Jul 3, 2020

Pending PR for the syntax change: php/php-src#5796

@derrabus derrabus force-pushed the improvement/route-attributes branch 5 times, most recently from a1962c0 to ee74cd5 Compare July 5, 2020 13:20
@derrabus
Copy link
Member Author

derrabus commented Jul 7, 2020

I've pushed an update to this PR the other day.

  • The PR is now incompatible with 8.0.0alpha1 and requires the changes of Attribute Amendments php/php-src#5751 to run.
    • PhpAttribute has been renamed to Attribute
    • The allowed targets of the Route attribute have been set to class and method (just like the annotation).
    • Now, we need to explicitly allow the attribute to be applied multiple times to the same structure, so I did just that.
  • I've duplicated all test fixtures of AnnotationClassLoaderTest and rewrote the annotations to attributes. So we're running the same test suite for annotations and attributes now.

Some tests mocked Doctrine's annotation reader. I rewrote those test to use an actual annotation reader instead. It might be a good idea to backport that change, in order to ease the maintenance.

@derrabus derrabus force-pushed the improvement/route-attributes branch from ee74cd5 to 17e221c Compare July 7, 2020 07:59
@derrabus
Copy link
Member Author

derrabus commented Jul 7, 2020

I might need some help with getting Travis green: https://travis-ci.org/github/symfony/symfony/jobs/705695329

On the php 7.4 run, it looks like some piece of code is trying to parse my new attribute (which only works on php 8). Anything I can do to prevent that?

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Jul 7, 2020

patch .github/patch-types.php?

@derrabus derrabus force-pushed the improvement/route-attributes branch from 17e221c to 76d0e91 Compare July 7, 2020 12:58
@derrabus
Copy link
Member Author

derrabus commented Jul 7, 2020

patch .github/patch-types.php?

That did not help, apparently. 🙁

@derrabus derrabus force-pushed the improvement/route-attributes branch from 76d0e91 to 93e199c Compare July 9, 2020 14:52
@moliata
Copy link

moliata commented Jul 9, 2020

@javiereguiluz Just to chime in, @@ is still in "unknown status" given that it raises ambiguity in the PHP parser. Thus, whether the new syntax will be used depends on the namespaced names as tokens RFC.

@derrabus
Copy link
Member Author

derrabus commented Jul 9, 2020

PHP attributes are basically a moving target at the moment. Just look at the changes between the alpha1 and alpha2 releases. And because I need a working testsuite, I won't anticipate any syntax changes until they actually hit the php 8 nightly build on travis.

Nevertheless, I think working with attributes at this early stage can be very helpful:

  • We can find out if attributes are helpful and how we can make use of them in Symfony.
  • We can give early feedback to the php dev team, which in turn might help them to fine-tune the feature before the final release.

Since Symfony 5.2 will stabilize together with php 8, I'm marking this PR as ready now. The current implementation of the PR works find with the alpha2 of php 8. If the PR gets merged, I'll monitor the php 8 build on Travis and adjust the implementation if necessary.

@fabpot
Copy link
Member

fabpot commented Sep 7, 2020

Thank you @derrabus.

@fabpot fabpot merged commit d0c915c into symfony:master Sep 7, 2020
@derrabus derrabus deleted the improvement/route-attributes branch September 7, 2020 12:12
nicolas-grekas added a commit that referenced this pull request Sep 18, 2020
This PR was merged into the 5.2-dev branch.

Discussion
----------

Added missing changelog entries

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       | #37545 #37474
| License       | MIT
| Doc PR        | N/A

I've added the missing changelog entries for the two tickets above.

Commits
-------

14642fb Added missing changelog entries.
@TomasVotruba
Copy link
Contributor

TomasVotruba commented Oct 4, 2020

We've just added @Route attribute to @rectorphp:
rectorphp/rector#4350

Named parameters makes this very intuitive to migrate 👍


Note, there is no Symfony\Component\Routing\---->Attribute<----\Route class as in PR description.
The class is the same as before, ..\Annotation\Route.

@derrabus
Copy link
Member Author

derrabus commented Oct 4, 2020

@TomasVotruba Thank you, I have updated the PR description. The first two iterations of the attribute syntax required me to introduce a dedicated attribute class, so this might have been a leftover from that time.

@TomasVotruba
Copy link
Contributor

TomasVotruba commented Oct 4, 2020

@derrabus Thanks 👍
I understand that, I rarely update the PR descriptions after design changes in them.

Next step: #38309

@nicolas-grekas nicolas-grekas modified the milestones: next, 5.2 Oct 5, 2020
@fabpot fabpot mentioned this pull request Oct 5, 2020
wouterj added a commit to symfony/symfony-docs that referenced this pull request Oct 11, 2020
This PR was squashed before being merged into the 5.x branch.

Discussion
----------

[Routing] Document the Route attribute

This PR documents the new `#[Route]` attribute that was introduced with symfony/symfony#37474 and thus closes #14188.

For the routing configuration via Doctrine Annotations as well as PHP attributes, we use the very same class, `Symfony\Component\Routing\Annotation\Route`. This means that both mechanisms are equally powerful. Right now, there's nothing you can do with `@Route` that is impossible with `#[Route]` and vice versa. The main difference is that you don't need an external library for attributes because they're a native language feature.

Because of that, I'd like to shift the general recommendation to use annotation towards attributes and recommend annotations as the fallback for projects that need to remain compatible with PHP 7.

Right now, the `@Route` annotation is used throughout the documentation in two different ways:

1. Demonstrate how to use the annotation

In this case, I've added an additional code block that shows the same configuration for attributes. I've consistently placed the attribute block before the annotation block.

2. Give context about the route configuration.

When a code block illustrates the logic inside a controller action and the annotation is only used to provide context, I think it would create too much noise to show the attribute _and_ the annotation way. In `routing.rst`, I have replaced the annotation with an equal attribute in such cases. I think it would be a good idea to do the same with the rest of the documentation, but I'd like to discuss this with you before I change all those spots.

Commits
-------

4ca794e [Routing] Document the Route attribute
derrabus added a commit that referenced this pull request Nov 7, 2020
…ration of routing/serializer without doctrine/annotations (derrabus)

This PR was merged into the 5.2-dev branch.

Discussion
----------

 [FrameworkBundle] Allow to use attribute-based configuration of routing/serializer without doctrine/annotations

| Q             | A
| ------------- | ---
| Branch?       | 5.2
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | N/A
| License       | MIT
| Doc PR        | N/A

Follows #37474, #38525

Currently, we need `doctrine/annotations` to be installed in order to configure routing and serializer via PHP attributes. Given that for both components we can already replace Doctrine Annotations completely, I'd like to get rid of that limitation.

Commits
-------

e5492e2 [FrameworkBundle] Configure PHP Attributes without doctrine/annotations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature RFC RFC = Request For Comments (proposals about features that you want to be discussed) Routing Status: Reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants