Rechercher

À la découverte de Mercure


26 Août 2020 | 8 mins Arthur Jacquemin

Aujourd’hui, je vous fais découvrir ce qu’est Mercure, ses principes, puis on apprendra comment le mettre en place simplement avec Docker. Mercure est un sérieux concurrent aux classiques WebSockets et autres solutions similaires, car il tire parti de nombreuses nouveautés du Web (HTTP/2, SSE, …) et est supporté nativement par la plupart des navigateurs.

Logo de Mercure

En clair, c’est un protocole qui permet d’envoyer des push updates vers tout client HTTP.

Par exemple, une ressource de votre API est mise à jour, et vous souhaitez que les navigateurs ou smartphones connectés à votre application reçoivent le changement sans avoir à requêter l’API. Le tout est possible en temps réel grâce à Mercure !

Ce protocole est publié en tant qu’Internet Draft par Kévin Dunglas, il est donc encore jeune (le protocole, pas Kévin.. Enfin Kévin est encore jeune aussi mais… Hum, bref).

Cependant, j’ai décidé de vous le présenter car il est déjà stable et parfaitement utilisable pour vos applications (et déjà utilisé en production sur de nombreux projets).

Vous êtes des adeptes de la nouveauté ? Férus de conquête spatiale ? Fans de Freddy Mercury ? Alors entrez dans la fusée, attachez vos ceintures et gardez vos rations lyophilisées à portée de main, on part à la découverte de Mercure.

1. A kind of magic

Waw c’est magique !

C’est ce qui m’a traversé l’esprit la première fois que j’ai testé Mercure, tant c’est facile d’utilisation. Un magicien ne révèle habituellement pas ses secrets, mais vous m’avez l’air sympa, on va faire une exception.

Alors pour débuter la visite de Mercure, commençons par apprendre ensemble son langage…

Je vous présente tout d’abord le Hub, le serveur et le cœur de Mercure. C’est vers lui que sont publiés les Updates, et c’est lui qui s’occupe ensuite de les dispatcher à tous les clients abonnés aux ressources souhaitées.

Ces ressources sont définies par des Topics. Un topic représente une ressource, à laquelle on peut s’abonner, pour en recevoir les Updates. C’est une bonne pratique d’identifier un topic par une URI complète, par exemple : http://example.com/product/1 qui représente le produit d’ID 1. Une Update est donc la version mise à jour d’un topic.

Enfin, on a les Subscribers (clients HTTP) et les Publishers (par exemple votre API), dont les termes parlent d’eux mêmes : les premiers s’abonnent au Hub Mercure, afin de récupérer les Updates de certains topics, publiés par… Je vous le donne en mille… Les Publishers, exactement !

Note

Mercure utilise les SSE (Server Sent Events) pour pousser ses Updates

Schéma du fonctionnement de Mercure

C’est bon, vous avez tout compris… Plus qu’à mettre en pratique !

2. Mercure en pratique

La théorie ça va 5 minutes, mais je sens bien que vous trépignez d’impatience de tester par vous-même. Ça tombe bien, c’est maintenant !

Rien de tel qu’un petit exemple pour dompter la bête. Pour des besoins de reproductibilité et de facilité, nous allons utiliser l’image Docker de Mercure.

docker run \
-e JWT_KEY='astronautsKey' -e ALLOW_ANONYMOUS=1 -e CORS_ALLOWED_ORIGINS='*' -e PUBLISH_ALLOWED_ORIGINS='http://localhost' \
-p 3000:80 -d \
dunglas/mercure

Plusieurs choses à décortiquer. Mercure peut prendre plusieurs variables d’environnement en entrée pour fonctionner, mais voici ici parmi les plus importantes :

  • JWT_KEY : Ce paramètre est obligatoire. Les Publishers et Subscribers l’utilisent pour s’abonner et publier sur le Hub.
  • ALLOW_ANONYMOUS : Définit si les clients non authentifiés (sans JWT) peuvent s’abonner au Hub. On l’autorise pour l’exemple.
  • CORS_ALLOWED_ORIGINS : Définit les règles CORS du serveur Mercure. Pour l’exemple, nous autorisons les clients de tous domaines.
  • PUBLISH_ALLOWED_ORIGINS : Les domaines autorisés à publier des updates sur le Hub.

Et… C’est tout ! Vous avez un serveur Mercure qui tourne sur votre machine. Rendez-vous sur votre http://localhost:3000 pour vérifier.

Connectez-vous sur http://localhost:3000/.well-known/mercure. Bienvenue sur votre Hub ! Normalement, ce dernier vous affiche un petit message…

Missing “topic” parameter

En effet, il s’attend à ce que vous lui précisiez sur quel topic vous souhaitez écouter les updates. Il suffit de rajouter ce paramètre dans l’URL du hub : http://localhost:3000/.well-known/mercure?topic=http://example.com/message/1.

Parfait, vous écoutez donc le topic http://example.com/message/1.

Important

Attention à ne pas confondre. Il ne s’agit pas à proprement parler d’une URL mais plutôt d’une URI (Uniform Resource Identifier), qui identifie une ressource. En soi vous pourriez mettre n’importe quel identifiant ici (e.g. juste messages, ou message/1, mais il est fortement conseillé de préférer indiquer une URI complète.)

Il est temps de publier une Update sur votre Hub Mercure pour voir ce qu’il se passe. Pour cela, nous simulerons notre Publisher avec Postman.

Pour autoriser notre Publisher à pousser des Updates sur le Hub, nous devons générer un JWT (Json Web Token) . Rendez-vous sur jwt.io. Dans la partie Payload, insérez ce tableau :

{
    "mercure": {
        "publish": ["*"]
    }
}

Cette configuration autorise à publier des updates publiques. Enfin, dans la signature, remplacez le secret par la JWT_KEY que vous avez renseignée plus tôt dans la commande Docker (e.g. astronautsKey). Collez le JWT généré dans la partie autorisation de Postman.

La requête que nous allons faire est de type POST, sur l’adresse du hub : http://localhost:3000/.well-known/mercure.

Utilisez un body de type x-www-form-urlencoded pour les paramètres, qui sont les suivants :

  • topic : Ce paramètre est obligatoire, il identifie la ressource à publier. Indiquez le même que celui sur lequel vous écoutez (e.g. http://example.com/message/1)
  • data : Le but, c’est d’envoyer une update. C’est dans le paramètre data que vous allez populer votre update avec les données souhaitées. Vous pouvez y mettre ce que vous voulez.

Note

Il existe d’autres paramètres optionnels possibles, que vous pourrez retrouver sur la documentation officielle de Mercure.

Gardez un oeil sur l’onglet de votre navigateur connecté au Hub, et lancez la requête.

Tadam ! Vous devriez voir un message apparaître. Bravo, vous avez envoyé votre premier update avec Mercure.

Attention

Si rien ne s’affiche, rafraichissez la page, et relancez votre requête. Si toujours rien ne s’affiche et que Postman ne vous renvoie pas l’identifiant de l’Update, vérifiez votre JWT.

Et voilà ! Amusez-vous à changer les topics, et savourez l’envoi d’updates en temps réel.

3. Abonnez-vous à vos évènements

Avant de finir, je vais vous présenter comment on s’abonne très simplement au Hub de Mercure. Car nous venons de tricher en nous connectant directement au Hub, mais ce que nous souhaitons, c’est bel et bien s’y abonner depuis un vrai client HTTP !

Créez-vous un simple fichier HTML, et insérez-y ce code dans une balise script :

const url = new URL('http://localhost:3000/.well-known/mercure'); // URL de notre Hub Mercure
url.searchParams.append('topic', 'http://example.com/message/1'); // On ajoute les topics auxquels on souhaite s'abonner
url.searchParams.append('topic', 'http://example.com/message/{id}'); // Il est possible d'utiliser un topicSelector afin de sélectionner plusieurs topics en même temps
const eventSource = new EventSource(url);

eventSource.onmessage = ({data}) => {
    console.log(data);
}

Comme vous pouvez le voir, on peut s’abonner à plusieurs topics, ce qui facilite bien des choses.

Mercure repose sur les SSE, on utilise donc l’API JavaScript EventSource pour écouter les updates qui nous sont envoyés. Ainsi, si vous postez encore un Update avec Postman, vous verrez dans votre console les data de cette Update qui s’affichent. À vous à présent d’imaginer une multitude de use cases !

Conclusion

Voilà qui conclut un très rapide tour d’horizon de Mercure. Vous savez à présent comment il fonctionne, et vous êtes capables de le configurer et l’utiliser simplement dans n’importe laquelle de vos applications. Bien évidemment, ce protocole est beaucoup plus complet qu’il n’y parait, et il y aurait beaucoup d’autres choses à dire, mais je n’en dévoilerai pas plus dans cet article d’introduction.

GIF Keep your secrets

Cependant, un codelabs est prévu très bientôt pour approfondir tout cela, et découvrir plein d’autres choses, notamment comment sécuriser les connexions, utiliser Mercure dans une application Symfony… Le tout sur la plateforme Eleven’s Codelabs.

Je vous invite bien entendu à consulter la documentation officielle de Mercure qui est extrêmement bien faite, afin de pousser votre exploration encore un peu plus loin.

Je vous souhaite de nombreuses et très belles aventures avec Mercure.

Auteur(s)

Arthur Jacquemin

Développeur de contenu numérique à destination de l’Internet @ ElevenLabs_🚀

Utilisation hors-ligne disponible