Skip to content

feat: add Twig helper generating hub URLs and setting authorization cookies #62

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 7 commits into from
Jul 2, 2021

Conversation

dunglas
Copy link
Member

@dunglas dunglas commented Jun 25, 2021

This PR dramatically improves the Developer eXperience of the Mercure integration in Symfony. It can be considered as part of the Symfony UX initiative.

At a glance, it introduces a new Twig helper allowing to generate the URL of the Hub and to automatically set the cookie required to use the authorization mechanism:

<script>
    const es = new EventSource(`{{ mercure('https://example.com/users/1', {
        subscribe: ['https://example.com/users/{id}', 'https://example.com/books/{isbn}']
    }) }}`);
    es.onmessage = console.log;
</script>

In a single call, this helper:

  1. returns the URL of the Mercure hub with the properly encoded topic query parameters (currently, passing the URL of the Hub to Twig requires some collaboration from a controller, or to define a global environment variable, and encoding the topics may not be straightforward for users not familiar with modern JavaScript APIs)
  2. sets a mercureAuthorization cookie containing the valid JWT to subscribe to topics matching the passed URI templates (currently, setting this cookie require collaboration from the controller, and isn't straightforward)

Subscribing to Mercure updates can be considered as part of the View layer. This new helper allows subscribing directly from Twig, without having to write any boilerplate code.

Then, a call to HubInterface::publish() from any service or controller is enough for the client to receive the push!

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mercure\HubInterface;
use Symfony\Component\Mercure\Update;
use Symfony\Component\Routing\Annotation\Route;

class MercureController extends AbstractController
{
    #[Route('/publish', name: 'publish')]
    public function subscribe(HubInterface $hub, Request $request): Response
    {
        return new Response(
            $hub->publish(new Update('https://example.com/users/1', $request->get('data')))
        );
    }
}

This will also allow improving the developer experience of Symfony Turbo by having native support for authorization.

Here is the list of all available options:

mercure(['https://example.com/users/1', 'https://example.com/books/abc'], {
    subscribe: ['https://example.com/users/{id}, 'https://example.com/books/{isbn}'],
    publish: ['https://example.com/users/{id}, 'https://example.com/books/{isbn}'],
    hub: 'another-hub'
})

I also revamped a bit #60 (cc @norkunas) to leverage the new infrastructure. In a following PR, I'll use this to allow to automatically clear the cookie when the user logs out from the site.

PR for MercureBundle: symfony/mercure-bundle#57

TODO:

  • add more tests

@dunglas dunglas force-pushed the feat/twig-helper branch from 670f7b0 to f8696e6 Compare June 25, 2021 15:59
Copy link
Member

@weaverryan weaverryan left a comment

Choose a reason for hiding this comment

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

This is a very compelling idea :)

@dunglas dunglas force-pushed the feat/twig-helper branch from 79092e7 to b5d97a3 Compare June 27, 2021 12:34
@dunglas dunglas force-pushed the feat/twig-helper branch from 939eb1b to 5cd7372 Compare June 28, 2021 17:31
@dunglas dunglas force-pushed the feat/twig-helper branch from 0779c7d to ab2b33e Compare June 28, 2021 22:17
@dunglas dunglas merged commit aac2735 into symfony:main Jul 2, 2021
@dunglas dunglas deleted the feat/twig-helper branch July 2, 2021 09:11
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

Successfully merging this pull request may close these issues.

4 participants