Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using blocking REST requests to implement publish/subscribe

I've recently been asked to investigate the feasibility of integrating with a phone system vendor who wants to make phone events (e.g. line ringing, extension answered, call cleared) available using a RESTful web service.

I pointed out that REST is a request/response protocol and they were doing publish/subscribe. The solution they were suggesting was to make an HTTP REST request which would block and then eventually respond if and when an event was available - or time out.

Either way, another request would be made to get the next event and so on ad infinitum.

This idea made me cringe, but I was assured that the iPhone "push" e-mail operates this way.

Is this a reasonable use of REST?

like image 426
Mike Scott Avatar asked Sep 23 '10 15:09

Mike Scott


1 Answers

I would say that it doesn't fly well with the REST architectural style (mainly because REST constrains it to stateless client server interactions). However, the web is abundant with solutions that do long polling, and it more or less works, in spite of not being in the spirit of the web.

First, a note on architecture: Implementing pub/sub within REST merely means that the publisher adds items to a list which then is made available to subscribers. Subscribers poll the list. There are ways of crafting this to ensure once-and-only-once while maintaining message order and (a form of) guaranteed delivery, albeit asynchronous. It scales really well, and is really resilient.

My first piece of advice would be to make it optional, so that clients that can't perform long polling (or don't want to) can do so. I would even go so far as to say that if a generic client (like Google) the default would be not to perform long polling, and that the server kicks the long polling in by way of a special shared understanding between your client and the server. That shared understanding could be a custom media type or a custom link relation, or even a custom HTTP header that generic clients wouldn't know about. Clients that do support your long poll would be coded to discover the capabilities of long polling, and invoke it as necessary, falling back to regular polling if the long poll fails (e.g. an intermediary blocks it somehow).

And instead of trying to do this on top of HTTP, I would suggest using a non-HTTP socket for this, to not violate the intentions of HTTP and effectively use HTTP as a transport protocol. See cometd.

My other piece of advice would be to ask the question how "real time" your clients have to be. If a few seconds latency is acceptable then you can do a great deal with regular polling, even for extremely large numbers of clients, due to the cacheable nature of solving this using regular polling.

like image 101
mogsie Avatar answered Oct 06 '22 00:10

mogsie