Learning WebSub (Part 2) : Building a WebSub `hub` using Ballerina

Ayesh Almeida
3 min readMar 8, 2023

--

Photo by La-Rel Easter on Unsplash

In my previous article I did a brief introduction to WebSub protocol. In this article we are going to implement a WebSub hub using Ballerina Websubhub standard library. If you need some heads-up on Ballerina language, please go through this article.

The use case we are going to implement is a weather-notification hub. News stations can subscribe to the hub to receive hourly weather updates for a particular location. In this example we will primarily focus on the relationship between the hub and the subscriber.

Following areas will be covered during this implementation:

  1. Basic WebSub hub implementation using Ballerian language.
  2. Implement a WebSub subscriber using Ballerina language.
  3. Integrating a 3rd party API to retrieve weather reports for a location.
  4. Connecting Apache Kafka message broker as a persistence layer for the WebSub hub implementation.

In this article we will cover first two points and the rest will be covered during the upcoming blog posts.

WebSub Hub Implementation

Ballerina Websubhub standard library provides a thin-API layer to implement WebSub compliant hubs. If we go through the API specification of Websubhub standard library we can easily understand the APIs which needs to be implemented.

In Ballerina language, WebSub hub is designed in the form of listener and a service.

  • websubhub:Listener: A listener end-point to which websubhub:Service could be attached.
  • websubhub:Service: An API service, which receives WebSub events.

The websubhub:Listener serves as a wrapper for an HTTP listener, which makes an HTTP endpoint available for subscribers and publishers to send requests to. Each time a request is made to the websubhub:Listener endpoint, the corresponding API within the websubhub:Service that is attached to the websubhub:Listener will be triggered.

Here’s an example of what the basic hub implementation will look like:

Above code will start an HTTP endpoint on port 9000 and attach the websubhub:Service to /hub service-path. Publishers and subscribers can send request to hub using http://localhost:9000/hub URL.

In our example hub implementation, subscribers are subscribed for weather alerts for a particular location. A subscriber can send the location name as the hub.topic parameter in the subscription request.

Hub should maintain two states.

  1. Locations to which weather-notifications should be generated.
  2. News receivers who are subscribed for weather alerts.

Available locations can be managed as a string[] and the News receivers will be managed as a map<websubhub:VerifiedSubscription> . News receivers will be assigned an Id which will be derived using hub.topic and hub.callback parameters in the subscription request.

With the above constraints our hub implementation will look like this:

Note that in our hub implementation following remote methods has been disabled since they are related to publisher related functionalities.

  • onRegisterTopic
  • onDeregisterTopic
  • onUpdateMessage

To improve the readability of the code we will add following additional utility methods to our implementation.

The hub implementation is able to record the locations and registered news receivers. Now, we want to implement the functionality to periodically send weather alerts to the registered news receivers. In the initial state we will have predefined set of alert templates which would be customized according to location.

Here we have used websubhub:HubClient to deliver content to the news receivers. A websubhub:HubClient has a one-to-one mapping to a WebSub subscriber; in this case to a news receiver.

With these changes we can improve the onSubscriptionIntentVerified remote method in the hub service.

In the implementation I have used several concurrency constructs in Ballerina language. Please refer to this article for more details on Ballerina concurrency.

WebSub Subscriber Implementation

In our example WebSub subscriber represents a news receiver. We can implement a simple subscriber using the following code.

One important thing to be noticed here is that subscriber is another service which exposes an HTTP endpoint.

In websub:SubscriberServiceConfig annotation we need to provide the target parameter (which is a tuple). In the target parameter, first value represents the hub URL and the second value represents the hub.topic parameter which should be used in the subscription request.

In this article we have discussed how to implement a basic WebSub hub and a subscriber using Ballerina language. In the next article, we will be covering how to integrate 3rd party APIs to retrieve weather notifications.

--

--

Ayesh Almeida
Ayesh Almeida

Written by Ayesh Almeida

A Tech Enthusiast who wants to build simple solutions for complex problems.

No responses yet