views:

27

answers:

1

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?

+1  A: 

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.

mogsie
Thanks for the detailed response. The only issue I have with it is that pub/sub is asynchronous by its very nature and any form of polling is missing the point that events should be pushed asynchronously, not pulled. Response has to be real-time as we need to do screen popping as soon as an extension is lifted to answer an incoming call. On a busy installation, events can be every second or even faster. I'm guessing that the server will return a token or timestamp which can be used in the next request to ensure no events are missed.
Mike Scott
Yeah. Think how twitter uses cursor based pagination: http://apiwiki.twitter.com/Twitter-REST-API-Method:-friends%C2%A0ids -- next_cursor and previous_cursor could be thought of as links to the next / previous pages. These pages work even if the list underneath changes. Index based pagination doesn't work for lists that change a lot.
mogsie