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 a new Link component #22273

Closed
wants to merge 14 commits into from
Closed

Conversation

dunglas
Copy link
Member

@dunglas dunglas commented Apr 4, 2017

Q A
Branch? master
Bug fix? no
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets n/a
License MIT
Doc PR todo

This a proposal to extract HTTP preloading features introduced in #21478 in their own component.

There are some good reasons to do it:

  • HTTP preloading is not (only) about assets: this standalone component could be very useful to replace resources embedding in APIs by HTTP/2 pushes like described in this article by @evert. In such case, there is no reason to carry the whole asset component for an API.
  • There is no dependency nor relation at all between the code of the asset compnent and the one I've added for Preloading features
  • It makes the code cleaner (no more optional dependency in the Asset Twig extension)

This component would also better fit in HttpFoundation than in Asset. But there is no dependency between it and HttpFoundation and it can easily be used with PSR-7 too, so IMO it better belongs in a standalone component.

Btw, ~~~I plan to add support for prefetching to this component. Except a PR soon.~~~ Prefetching and prerendering support added in this PR.

ping @symfony/deciders

@dunglas
Copy link
Member Author

dunglas commented Apr 4, 2017

A better name would probably be "Link Component": https://html.spec.whatwg.org/multipage/semantics.html#links

@nicolas-grekas nicolas-grekas added this to the 3.3 milestone Apr 4, 2017
@nicolas-grekas
Copy link
Member

Added to the 3.3 milestone because this is only about new features already planned for 3.3

@stof
Copy link
Member

stof commented Apr 4, 2017

Not changing the service definition for assets.preload_manager looks suspicious to me (and btw, the name should be changed)

@dunglas
Copy link
Member Author

dunglas commented Apr 4, 2017

I've renamed the component Link, added support for generic "Link" headers (preloading and resource hints) and introduced new Twig helpers for dns-prefetch, preconnect, prefetch and prerender.

This new component now support all types of prefetching and is smart enough to manage generic Link headers (for instance, when it will be available https://github.com/api-platform/core/blob/master/src/Hydra/EventListener/AddLinkHeaderListener.php in API Platform may be removed).

@stof comment also addressed.

@dunglas dunglas force-pushed the extract_preload branch 2 times, most recently from c0d3a31 to e47b413 Compare April 4, 2017 17:13
@@ -39,6 +39,7 @@
"symfony/console": "~3.3",
"symfony/css-selector": "~2.8|~3.0",
"symfony/dom-crawler": "~2.8|~3.0",
"symfony/links": "~3.3",
Copy link
Contributor

Choose a reason for hiding this comment

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

symfony/link

"symfony/http-kernel": "^2.8 || ^3.0"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Preload\\": "" },
Copy link
Contributor

Choose a reason for hiding this comment

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

Symfony\Component\Link\

@dunglas dunglas changed the title Add a new Preload component Add a new Link component Apr 5, 2017
@dunglas dunglas force-pushed the extract_preload branch 2 times, most recently from d0f40a0 to ff6b790 Compare April 5, 2017 06:48
@dunglas
Copy link
Member Author

dunglas commented Apr 5, 2017

Tests should be green after the merge.

{
protected function setUp()
{
if (!class_exists(LinkManager::class)) {
Copy link
Member

Choose a reason for hiding this comment

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

I would add symfony/link to the require-dev section of the composer.json file instead.

@@ -208,6 +208,10 @@ public function load(array $configs, ContainerBuilder $container)
$this->registerPropertyInfoConfiguration($config['property_info'], $container, $loader);
}

if ($this->isConfigEnabled($container, $config['links'])) {
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 test for the Link component to be present first and throw a meaningful exception if not present.

Copy link
Member Author

@dunglas dunglas Apr 5, 2017

Choose a reason for hiding this comment

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

Link should not be a mandatory component. You mean throwing if enabled is set to true but the component not installed?

Copy link
Member

Choose a reason for hiding this comment

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

yes, we did that recently for other optional dependencies too


<service id="links.link_manager" class="Symfony\Component\Link\LinkManager" public="false" />

<service id="links.link_listener" class="Symfony\Component\Link\EventListener\LinkListener">
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 private?

Copy link
Member Author

Choose a reason for hiding this comment

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

IIRC, event listeners can't

Copy link
Member

Choose a reason for hiding this comment

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

since #20953 they can

@@ -62,6 +63,10 @@
<xsd:attribute name="path" type="xsd:string" />
</xsd:complexType>

<xsd:complexType name="links">
<xsd:attribute name="enabled" type="xsd:boolean" />
Copy link
Member

Choose a reason for hiding this comment

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

Does it make sense to set this to xsd:string to allow using a DI parameter in the config?

Copy link
Member Author

Choose a reason for hiding this comment

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

All others similar parameters use xsd:boolean. If we want to change this behavior, we should do it in another PR for all enabled parameters.

Copy link
Member

Choose a reason for hiding this comment

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

maybe something to "fix" by adding a new "boolean" type, borrowed from the XSD of the DI XmlFileLoader? (in another PR)

@@ -238,6 +238,9 @@ protected static function getBundleDefaultConfig()
'log' => true,
'throw' => true,
),
'links' => array(
'enabled' => !class_exists(FullStack::class),
Copy link
Member

Choose a reason for hiding this comment

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

What about adding the component as a dev dependency to the composer.json file instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

It is, it's not related.

Copy link
Member

Choose a reason for hiding this comment

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

sorry, I misread the code

*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class LinkManager implements LinkManagerInterface
Copy link
Member

Choose a reason for hiding this comment

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

final?

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 on my side but I think it's against our CS (maybe @final). ping @nicolas-grekas

Link Component
==============

The Link component manages link between resources. It is particularly useful advise clients
Copy link
Member

Choose a reason for hiding this comment

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

[...] manages links between [...]

Copy link
Member

Choose a reason for hiding this comment

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

[...] useful to advise [...]

"symfony/http-kernel": ""
},
"require-dev": {
"symfony/http-kernel": "^2.8 || ^3.0"
Copy link
Member

Choose a reason for hiding this comment

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

The EventDispatcher and HttpFoundation components are used by the LinkListenerTest class too.

@teohhanhui
Copy link
Contributor

Please, call this "HttpLink".

@dunglas
Copy link
Member Author

dunglas commented Apr 5, 2017

@teohhanhui it's not really related to HTTP (only the listener is). It can also handle HTML links and in general links in any other protocol.

@dunglas
Copy link
Member Author

dunglas commented Apr 5, 2017

@xabbuh's comments fixed

@teohhanhui
Copy link
Contributor

I believe it's defined in RFC 5988 - Web Linking. Perhaps it can be named WebLink or ResourceLink.

@dunglas
Copy link
Member Author

dunglas commented Apr 5, 2017

I like WebLink.

@andersonamuller
Copy link
Contributor

WebLink is fine, but then the buildValues method on LinkManagerInterface should not mention HTTP headers

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Validator\Validation;
use Symfony\Component\WebLink\WebLinkManagerInterface;
Copy link
Member

Choose a reason for hiding this comment

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

this interface does not exist anymore

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.

👍

@fabpot
Copy link
Member

fabpot commented Apr 10, 2017

Some tests are broken on Travis.

@dunglas
Copy link
Member Author

dunglas commented Apr 10, 2017

@fabpot IIUC, only because the component is not available on Packagist yet (DEPS=low)?

@fabpot
Copy link
Member

fabpot commented Apr 10, 2017

Thank you @dunglas.

@TomasVotruba
Copy link
Contributor

Great job!

I almost missed it... is there a post somewhere? I couldn't find any. Or is it reverted?

@jdreesen
Copy link
Contributor

jdreesen commented May 7, 2017

There is New in Symfony 3.3: WebLink component.

@TomasVotruba
Copy link
Contributor

@jdreesen Ah, thank you. I probably looked for "Link*".

javiereguiluz added a commit to symfony/symfony-docs that referenced this pull request Oct 30, 2018
This PR was merged into the 3.4 branch.

Discussion
----------

Add docs for the WebLink component

The WebLink component is available since Symfony 3.3, but I never took the time to add the docs (however, a blog post explaining how to use it was available).

This documentation is based on https://dunglas.fr/2017/10/symfony-4-http2-push-and-preloading/.
If necessary, I can grant any copyright regarding this post to the Symfony project.

symfony/symfony#21478
symfony/symfony#22273
Closes #7515.

Commits
-------

91ee3bc Fix RST
ea7b3da @nicolas-grekas' review
38fda88 fix build
e12e776 RST
088690f Fix link
e3d4036 RST
178821e refactor
9f4ae9b fix typo
6beb4eb Add docs for the WebLink component
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.

None yet