PubSubHubbub for APIs

PubSubHubbubwas initially created for feeds, because the polls/update ratio is usually quite high for them. Unfortunately, this ratio is also often times very high for APIs. Generally, we push people into implementing feeds rather than APIs for their content, as feeds are standard, and once a developer has created an app that is able to consume and RSS feed from Flickr, it is able to consume a feed from Tumblr, a feed from ReadWriteWeb or a feed from Craigslist. Feeds are the web’s lingua franca! Yet, in some cases, having a custom JSONAPI just makes more sense. Here is how to support PubSubHubbub with your API.

Identify the resource

It’s the first step : what are people polling the most on your service? It could be the weather in a given geographic area, it could be the price of an item in your catalog, it could be the profile information of a user in your system… etc.
Once you have identified this resource, you need to make sure you can track when the change in this resource happens. Generally, it’s hard to use something that changes constantly, like a stock price. In such cases, you want to define levels that will trigger notifications, for example.

Discovery

PubSubHubbub is a layer on top of your existing API, but you need to programmatically indicate anyone polling your API that the content their polling is available for them in a push fashion. First, create a publisher account with Superfeedr, then, follow the instructions to create your hub. For the sake of clarity, let’s assume you’ve chosen publisher.superfeedr.com.
You now need to add an HTTP header to your API responses which mentions this hub. The header you want to use is Link and you actually want to add 2 : one for the hub itself and one of the resource, like this :Link:<http://publisher.superfeedr.com/>;rel="hub"Link:<http://service.tld/api/resource>;rel="self"

Securing subscriptions

People can now start to subscribe to your content. Odds are that your API is protected, so you may not want anyone to subscribe to the content :) In your hub’s settings, you’ll see that you can define a Subscription callback. This callback is actually an HTTP url on which we will echo all subscriptions to your content, including the HTTP headers and any additional parameter provided by the subscriber.

Based on the HTTP status code that your callback returns, we will accept or refuse subscription on your behalf, and we will also show any error message back to the subscriber. If your app requires authentication with OAuth, you can just refuse subscriptions that do not provide any.

Once you accept the subscription, we will notify that subscriber when the content is updated. Also, subscriptions have an expiration date, which means that subscribers will need to re-initiate subscriptions after some time. This is quite handy to remove disrespectful subscribers.

Notifications

This is the last step. Superfeedr needs to know about the updated content, so we can notify your content subscribers, and for us to know that your content has been updated, you need to ping us. There are several ways to do so :

Fat pings : rather than have us poll you, you directly fat ping the content to https://publisher.superfeedr.com. We will parse the content and push it forward to your subscribers. We usually recommend it when the ping/subscription ratio is quite high. In other words, if at least one subscriber is subscribed to most of the pings you send, it’s better to fat ping us. However, we ask that you sign these requests to avoid forgery.

Light pings : If the number of pings you make is much higher than the number of subscriptions to your content, then, you’re better off with light pings : you tell Superfeedr which url has been updated and we will poll it right away. Of course, you can also indicate which credentials we should use (including OAuth and OAuth2 headers), so your content is always protected.

After that, not only will you see a decrease in your bandwidth consumption, as well as server load, but you will also start to see innovative applications as it’s now much much easier to consume your content from your API!