|Design Challenges: building a REST API which calls a 3rd Party REST API||Andrew Little||10/2/12 7:45 AM|
I am working with a team tasked with building a REST API which in turn makes calls into a 3rd party REST API. So if I make a call to GET followers/ids, then our API will in turn call the 3rd party GET followers/ids, then perform some basic processing to the 3rd party results before returning to the caller.
The challenge identified by the team is that we do not control the performance of the 3rd party REST API, and therefore it's a risk to make these 3rd party calls in a synchronous manner. Arguments I have heard is that a long running 3rd Party call would keep a thread open for an extended period of time and we could start to see outages in high traffic periods when 3rd party calls are taking a long time. The solution proposed is to move to a long polling/async approach. In this approach, the caller of GET followers/ids is immediately returned a unique Call ID and then asked to poll for the results. On the server side, the call is processed in a queue. This does certainly release the thread, but then requires the callers to poll for results.
I'm not a seasoned REST API architect, but this "long polling"/asynchronous approach does not seem to be the best approach to solving the design problem of an API which calls a 3rd party API.
Wondering if anyone could suggest an alternate solution, or point me to some examples in which a REST API does exactly what we're trying to achieve.
My arguments against long polling:
|Re: [api-craft] Design Challenges: building a REST API which calls a 3rd Party REST API||sune||10/2/12 8:34 AM|
Ah, basically you want to add some kind of caching mechanism, so that you can speed up the requests, and keep feeding your clients.
As long as no-one bypasses your server the REST part should work out fine.
|Re: [api-craft] Design Challenges: building a REST API which calls a 3rd Party REST API||Ronnie Mitra||10/2/12 8:36 AM|
My definition of long polling is when a client executes long blocking GETs until a response is received. Is this what you are trying to do? It sounds more like your clients will be executing short GETs to check on the status of the response periodically.
From the scenario you describe it sounds like requests could take a long time to be resolved. In that case you might consider using a callback pattern in which the client becomes a server and waits for a response (i.e. the server sends the response message as a new HTTP request to the client). I would classify this pattern as more complex for the client than polling, but will likely be less of a thread/connection strain on your server if that is important.
Stateful connections (like websockets) might also be suggested for situations like this, but it doesn't sound like that is the right answer here as you don't seem to have a need for bi-directional or low latency communication and you would be leaving the realm of HTTP.
Personally, I'd choose the polling method as it meets most of your criteria. I'm not sure why you think it's not RESTful, but I make a point of not going down that road! Off the top of my head, I think the Twilio API has some examples of the callback pattern and Subbu's REST cookbook has examples of the polling style.
|Re: [api-craft] Design Challenges: building a REST API which calls a 3rd Party REST API||Andrew Little||10/2/12 10:00 AM|
Thanks for the response, Ronnie.
I think I misused long polling. I was attempting to describe standard client server polling: 1. client makes request and server responds with ACK, 2. client polls the server until a full response is returned.
Here is a significant piece of information that I left out unintentionally. In all but exceptional cases, the 3rd party API (in this case, Twitter) will respond very quickly and the API calling the 3rd party will experience almost no delay. So my problem with the polling solution is that we're introducing a more complicated polling behavior on all client apps to handle the exceptional case in which the 3rd party API is experiencing delays (perhaps high load situations). I believe we could get away with making all calls on the API in a synchronous fashion, though have not proven this theory.
I like your thoughts on the callback pattern. I'll take a look at that as well.
|Re: [api-craft] Design Challenges: building a REST API which calls a 3rd Party REST API||mikeschinkel||10/2/12 10:57 AM|
On Oct 2, 2012, at 1:00 PM, Andrew Little <aali...@gmail.com> wrote:
|Re: [api-craft] Design Challenges: building a REST API which calls a 3rd Party REST API||Greg Brail||10/2/12 11:54 AM|
When you talk about making API calls in a synchronous manner, are you worried about the latency on the client, or thread usage on the server?
I agree that building a server that blocks a thread while waiting for a long-running API call to return is not going to scale if you have more than several tens of concurrent users of your API. (While OTOH if you only have a few users it won't matter.)
From your discussion about threads, it sounds to me like you are more worried about thread usage on the server than blocking the client -- and in that case, you need to do this using a proxy that uses async I/O. There are certainly products and tools out there that can do that (Apigee included) along with open-source libraries for async servlets and async HTTP clients (to use Java examples that I'm familiar with).
|Re: [api-craft] Design Challenges: building a REST API which calls a 3rd Party REST API||Daniel Crenna||10/2/12 12:23 PM|
One approach that might work well for you is to send your call asynchronously, but don't push it to a background queue right away. Give it the opportunity to complete quickly. You introduce a touch of complexity because clients may get one of two responses depending on the latency, but at least you cover 80% of cases and have a graceful way to handle the others.
|Re: [api-craft] Design Challenges: building a REST API which calls a 3rd Party REST API||Andrew Little||10/2/12 1:03 PM|
You are correct, I am only concerned about thread usage (scaling issues) on the server side. Handling things asynchronously on the client side is easy for us to do, so long running request/response cycles are not a problem (client side).
Thanks for the idea of using a proxy with async I/O. I think this will give me some ideas to research and present some options for our API. My aim is resolve the scaling concerns I have been hearing, but to present a solution that hides any async complexity from the client side applications - i.e. keep the API very clean and free of any Call/Job ID references.
|Re: [api-craft] Design Challenges: building a REST API which calls a 3rd Party REST API||Andrew Little||10/2/12 1:06 PM|
Thanks, Dan. I like this hybrid approach, too. Ideally, I want to keep things very clean on the client side, because there may be many applications requiring such additional logic. However, this definitely ensures that in most cases (i.e. 80%), we'd get a quick response without entering the polling loop. Nice.
|Re: [api-craft] Design Challenges: building a REST API which calls a 3rd Party REST API||blongden||10/3/12 12:21 AM|
I've used this Hybrid approach too - having an expected ETA for a request so that my API can either return a 'real' response, or a 202 (with a link to a 'status' resource for the request). It does add a little complexity on the client side as it needs to handle both types of response - but it does work well.
You could perhaps minimise the additional complexity by using a hypermedia type which supports embedded documents - if the request completes (ie, is not queued), embed the result data in the response. If it does not complete and returns a 202, the real result could be an embedded resource in the status monitor for the queued job. At least for both of these response types, you have the same way of retrieving the data once it is ready. application/hal+json is one of the formats which does support embedded resources in a response, to reduce the 'chatty' api syndrome.