View
 

RESTful WebHooks

This version was saved 15 years, 2 months ago View current version     Page history
Saved by nathandw
on October 8, 2009 at 4:44:19 pm
 

 

 

Introduction

 

Hey all,

This page is dedicated to the development of standards/guidelines for RESTful WebHooks. This page should be used to throw around ideas about how it ought to be done. As these ideas become more structured and coalesce so may this page. I am no Wiki master so if you would like to define a more coherent structure please do. Please post any thoughts you may have in the comments section below, this will serve as a record for the reasoning behind changes in this document. Please avoid making significant changes to this document without first posting suggestions for "pier review." If you want to provide examples of your proposals please link to publicly accessible external documents, lets try to avoid cluttering the comments section with examples.

 

Note: This is still a very rough concept as such you should expect that the recommendations on this page will change.

 

What are RESTful WebHooks?

 

Briefly, some history and bearings to lay the groundwork for the definition. REST was first "fielded" by Roy Fieldings, in chapter 5 of his doctoral dissertation. See a more readable write-up at RestWiki. REST is, at its core, a sensible way tothink about and implement your URIs (the resources - nouns) and HTTP (the interaction with the URIs - verbs).

 

So when we talk about RESTful WebHooks, we're talking about:

 

"Extending our use of HTTP to include information and interaction about WebHooks, in a way that is in keeping with REST principles."

 

 

Why REST?

 

WebHooks naturally lends itself to a RESTful design pattern. WebHooks are simple HTTP messages that communicate a change in the state of a web resource. One of the goals of WebHooks is to create a truly programmable web: allowing regular users to connect the various web apps they use in new and creative ways. WebHooks provides a means to publish (push) events to the web and as such should speak the language of the web, RESTful HTTP.

 

The primary weakness of other protocols such as SOAP are that they require the consumer to understand the syntax of the envelope as well as the payload. This creates unnecessary complexity for a concept as simple as WebHooks. Imagine having to parse a SOAP envelope just to find out that it doesn’t actually contain anything and is just a notification of a change. Does this mean that we must abandon all things complex? Must we avoid XML Schema and service description languages because they are too complex? Not necessarily. RESTful WebHooks implementations are encouraged to embrace existing tools such as WSDL, WADL, and XML Schema -- when necessary; however, these tools should only be used to enhance the capabilities of a WebHook service and not as part of a required protocol. 

 

Discovery

 

RESTful WebHooks discovery is very simple. Issue a HEAD command for the resource you would like to hook. WebHooks returns the HTTP headers detailing the payload formats that the WebHook can communicate in as well as information about service description resources. This mechanism is so simple it can easily be performed by humans and bots alike. It also prevents us from having to define special URLs or repositories for WebHooks discovery; WebHooks are sewn directly into the fabric of the web. WebHooks enable intuitive scoped event subscription (as long as your urls are intuitive and scoped). For example I could add a WebHook that listens to CREATED events atwww.blog.com/posts/web-hooks and get notified about any new blog posts, or I could listen only for the UPDATED event of a particular post: www.blog.com/posts/post/2009/10/6/web-hooks.  Search engines could even provide notification of WebHooks support directly in search results. Below is an example of WebHooks discovery request (note that HEAD is used, this prevents us from downloading a 2 hour film just to get info about the hookability of the resource): 

 

HEAD http://www.webapp.com/resources/resource 

200 Ok 
Link : <http://www.subpubhub/myaccount/.../resources/resource>, rel="Subscriptions"  Link : <http://www.subpubhub/myaccount/.../help/resources/resource>, rel="Help" X-WebHooks-Allow : application/json, application/xml, application/atom+xml
X-WebHooks-Events : CREATED, ACCESSED, UPDATED, DELETED

“X-WebHooks-Allow” notifies us of the formats the WebHook can be broadcasted in. Header links are used to identify the location of subscription and help resources. Link headers could be used to add additional resource links for example a link to WADL or WSDL resources could be included.

 

Subscription

 

Subscribing to WebHooks is nearly as simple as discovery. We use the Subscription Link that was discovered for subscription tasks. Because a WebHook is a RESTful resource we can use standard HTTP methods. To check the status of a subscription we issue a GET command, to subscribe POST, to update PUT and to unsubscribe DELETE. 

 

Subscribe: 

 

=> 

POST http://www.subpubhub.com/account/.../resources/resource Content-Type : text/uri-list X-WebHooks-Accept : application/json, application/xml X-WebHooks-Events : CREATED, DELETED  http://www.myapp.com/mylistener
<= 201 Created Location : http://www.subpubhub.com/account/.../resources/resource/subscription/1234523

 

 
Link : <http://www.subpubhub/myaccount/.../resources/resource>, rel="Subscriptions"
 
Link : <http://www.subpubhub/myaccount/.../help/resources/resource>, rel="Help"
 

 

 

Subscription Status:

 

=> 

GET http://www.subpubhub.com/account/.../resources/resource/subscription/1234523  <=
200 Ok Content-Location : http://www.subpubhub.com/account/.../resources/resource/subscription/1234523
Link : <http://www.subpubhub/myaccount/.../resources/resource>, rel="Subscriptions"
 
Link : <http://www.subpubhub/myaccount/.../help/resources/resource>, rel="Help"
X-WebHooks-Allow : application/json, application/xml, application/atom+xml
X-WebHooks-Events : CREATED, DELETED

Update Subscription:

 

=> 

PUT http://www.subpubhub.com/account/.../resources/resource/subscription/1234523
X-WebHooks-Accept : text/json, text/xml
X-WebHooks-Events : UPDATED
<=
202 Accepted
Content-Location : http://www.subpubhub.com/account/.../resources/resource/subscription/1234523 
X-WebHooks-Allow : text/json, text/xml, rss/xml, atom/xml
X-WebHooks-Events : CREATED, UPDATED, DELETED
Link : <http://www.subpubhub/myaccount/.../resources/resource>, rel="Subscriptions"
 
Link : <http://www.subpubhub/myaccount/.../help/resources/resource>, rel="Help"
 

Unsubscribe:

 

=> 

DELETE http://www.subpubhub.com/account/.../resources/resource/subscription/1234523 X-WebHooks-Events : ALL

<=
202 Accepted 
 
X-WebHooks-Allow : application/json, application/xml, application/atom+xml
Link : <http://www.subpubhub/myaccount/.../resources/resource>, rel="Subscriptions"
 
Link : <http://www.subpubhub/myaccount/.../help/resources/resource>, rel="Help"
 

WebHooks subscriptions are pretty straight forward. There are a couple important details to point out. First, subscription can support authentication through standard HTTP headers (WWW-Authenticate) and the OPTIONS command can be used to determine what subscription options are allowed for a particular user. In general any user that has permission to get a WebHooks message should have full subscription privileges, but I can imagine circumstances where a user is allowed to unsubscribe but not re-subscribe. Another important feature of RESTful WebHooks is that it returns the URL at which the subscription resource resides; this URL is used to modify the subscription. This is a double edged sword; on one hand it improves security on the other it may require that the user store this URL in order to modify the subscription (if they wish to modify a subscription between event publications as events contain the id). I would recommend this approach to publicly subscribable WebHooks that do not require credentials. If the site requires authentication to subscribe then the target URL could be used as the ID for subscription operations. I have seen additional security measures prescribed for the subscription process; in particular Daniel Parker suggests that target URLs be sent confirmation messages to make sure that Evil Doers are not subscribing random URLs to WebHooks. I think this decision should be left to the provider, but I think we should establish guidelines for this approval process.

 

Publication:

 

Once subscribed the target URL will start receiving WebHooks messages. These messages should contain standard WebHooks information. The payload of the event should be of the X-WebHooks-Accept type specified in the subscription (assuming it was an X-WebHooks-Allowed type).

 

=> 

POST http://www.myapp.com/mylistener
Content-Type : application/json
Content-Location : http://www.webapp.com/resources/resource
 
X-WebHooks-Event : CREATED
<= 200 Ok
 
 
Link : <http://www.subpubhub/myaccount/.../help/resources/resource>, rel="Help"
 
Link : <http://www.subpubhub/myaccount/.../resources/resource/subscription/1234523>, rel="Subscription"
Link : <http://www.subpubhub/myaccount/.../resources/resource>, rel="Subscriptions"

The published event should identify the type of the payload using the Content-Type and should identify the resource that published this event using the Content-Location (or Location) HTTP attribute. The URL of the subscription resource is included using the X-WebHooks-Location and the event is specified with X-WebHooks-Event. In addition RESTful WebHooks could support batched notifications using HTTPs multi-part messages.

 

What is left?

 

The are a number of details that have been left out of this initial definition:

 

-          Support for canceling events, eg. returning 406 “Not Acceptable” or other codes to cancel events.

-          Should redirects be followed when publishing an event.

-          Should subscriptions be automatically dropped on certain response status-codes etc.

-          There is as yet no definition for pre and post event types.

-          What should the payload be? Should it be info about the event? Should it be the resource that raised the event? 

 

Part of the reason these, and other features, have not been addressed is because for the most part they rely on the policies of the event publisher. For example, canceling an event requires that the publisher wait for a response before continuing execution preventing send-and-forget publication. While I do not think RESTful WebHooks should mandate standards for these behaviors we should identify common patterns and recommend best practices for these different approaches.

 

 

 

Comments (0)

You don't have permission to comment on this page.