Real-time updates

Once your Shlink instance is set up, you may want to enable real-time updates to notify third parties when certain events occur.

Currently, Shlink supports the next technologies to publish updates.

  • Mercure hub: allows to subscribe to server-sent events. (Since v2.2.0).
  • RabbitMQ: to publish server-to-server updates (Since v2.10.0).
  • Redis pub/sub: to publish server-to-server updates (Since v3.2.0).

Warning

Real-time updates only work with RoadRunner, which is the case if you are using the docker image.

Topics and payloads

Regardless the technology used for publishing and subscribing to updates, the whole list of supported topics, together with their payloads can be found in Shlink’s Async API spec page.

Mercure hub server

The best option if you want to get real-time updates on a client-side web app, is by taking advantage of the integration with a mercure hub server.

Mercure provides server-sent events, so that consumers can subscribe to topics and get automatically notified when Shlink publishes an update for any of them.

Configure the mercure hub server

The mercure hub server will act as an intermediary between Shlink, which will publish updates on it, and consumers, which will subscribe to those updates and get notified by the hub.

The first thing you need to do is install the mercure hub server. There’s both a prebuilt dependency-less binary, and a docker image, which is the best option to use together with Shlink’s docker image.

Then you need to provide some config options to the mercure hub for the integration to properly work:

For new mercure versions (since 0.11):
  • SERVER_NAME: This env var should have the value ":80", in order to disable https. Just make sure you serve mercure behind a reverse proxy, and enable https there.
  • MERCURE_PUBLISHER_JWT_KEY and MERCURE_SUBSCRIBER_JWT_KEY: The same value provided to Shlink should be used for these two env vars, otherwise, the JWTs generated by Shlink will be rejected by mercure and neither publishing nor subscribing will be possible.
  • MERCURE_EXTRA_DIRECTIVES: if you want to consume updates from a browser web app (like shlink-web-client), this option should have the directive cors_origins followed by the domain/s from which you plan to consume mercure (for example cors_origins https://app.shlink.io), otherwise, it will reject the connection.
For legacy mercure versions (before 0.11 or using legacy prefix):
  • --jwt-key|JWT_KEY: The same value provided to Shlink should be used here, otherwise, the JWTs generated by Shlink will be rejected by mercure and neither publishing nor subscribing will be possible.
  • --cors-allowed-origins|CORS_ALLOWED_ORIGINS: if you want to consume updates from a browser web app (like shlink-web-client), this option should have the domain/s from which you plan to consume mercure (for example "https://app.shlink.io"), otherwise, it will reject the connection.

Interaction between the parts

Once installed, this is how Shlink, the mercure hub and consumers will interact:

  • Shlink knows Mercure hub’s public URL and the JWT secret key.
  • Shlink can generate JWTs for mercure, which only have permission for subscribing.
  • Shlink publishes updates to mercure when something needs to be notified to consumers.
  • Consumers get valid JWTs and the hub URL from Shlink’s REST API, by calling the mercure info endpoint.
  • Consumers subscribe to topics on the mercure hub using the JWT returned on previous request.
  • If the JWT expires, consumers can call the endpoint as many times as they need to get new JWTs.

This flow ensures the JWT key is never leaked by accident, and you need to have a valid Shlink API key in order to get valid JWTs for mercure.

Also, JWTs returned to consumers will only have permission to subscribe to updates. Only Shlink will be able to publish updates.

Note

If you use shlink-web-client to interact with your Shlink instance, it will work out of the box and consume updates from mercure, updating the UI in real-time where applicable.

RabbitMQ server

Starting with v2.10.0, Shlink supports publishing updates in a RabbitMQ server, which is a widely used technology for publishing and subscribing to server-to-server updates.

Configure the RabbitMQ server

The RabbitMQ server will act as an intermediary between Shlink, which will publish updates on it, and consumers, which will subscribe to those updates and get notified in real-time.

There are several ways to install RabbitMQ. The best option is to follow the official documentation.

Once the server is configured, you can provide the integration config to Shlink via installation tool or env vars.

Exchanges and queues

Shlink will create an exchange with its corresponding queue, for every operation defined in Shlink’s Async API spec.

The exchanges and queues are created in a “durable” way, with “direct” publishing type.

Redis pub/sub

Since Shlink v3.2.0, if you configured a redis server/cluster for caching, Shlink can also use that instance for real-time updates via redis pub/sub.

When this happens, the redis server/cluster will act as an intermediary where Shlink publishes the updates, and others can subscribe to them.