Asynchronous Messages - How do I handle Asynchronous API through Apigee

Not applicable

This question is probably related to HTTP/REST API design itself.

Lets say, I have a API that submits a sales order, and the sales order creation takes some time. I don't want my client to wait that long. Sometimes this wait can be greater than HTTP timeout.

Lets say, my backend service for this built over JMS/Amazon SQS.

Now:

  1. How do I design my API in this case
  2. How do I implement this API on Apigee
0 3 2,291
3 REPLIES 3

Not applicable

Following the the typical approaches used.

Poll Approach

  1. Submit the creation job, return a job identifier.
  2. Use the job identifier against a status API the retrieve the current job status.
  3. If the status is done, use the identifier to get the final result.
  4. Step 2 is the repeated poll step.
  5. Apigee can be used for repeated polling while client waits or Apigee can provide a status API which can be polled by the end client.

Callback Approach

  1. Submit the creation job with a callback url.
  2. The callback url is invoked with the result once the job completes.
  3. The callback url can be apigee proxy url which can do further processing.

Apigee's support of Nodejs can also be used for this usecase.

In addition to what @sriki77 mentioned, in case of polling approach you can use HTTP headers to indicate the aynchronous behaviour.

You can return a “202 Accepted” status to the client as response to an async API. The response entity of a 202 Accepted response should be a regular resource with only the information filled in that was available at the time the request was accepted. The resource should contain a “link” attribute that points to a status monitor that can be polled to get updated status information.

When polling the status monitor, it should return a “response” object with information on the current status of the asynchronous request. If the call has finished, the response should include the same headers and response body had the request been fulfilled synchronously.

After the response has been retrieved once with a status that is not equal to “202 Accepted”, the clients should not assume it will continue to be available. If no expectation is provided, client must be prepared to accept a 202 Accepted status for any request other than GET.

Checkout these interesting links -

http://restcookbook.com/Resources/asynchroneous-operations/ https://www.adayinthelifeof.nl/2011/06/02/asynchronous-operations-in-rest/

In addition to the above two answers, what is also interesting are the following questions which will define your final approach.

1. What is the client expecting after making the API call? Or what is the business use case?

Does the client wish to see the status after issuing the call, in the same transaction? i.e. you might not be blocking his/her UI but you would like some notification or toast once the call succeeds. Here the callback approach of @sriki77 works well.

Or does the client fire and forget and come back later (say to a dashboard) to see the status of the transaction? Here the polling approach will work. This could also be useful if you have intermediate statuses i.e in-process, dispatched, confirmed etc.

2. What is the manner in which you are making the callout from Edge?

Are you calling this URL via a Service Callout, via a target endpoint URL etc? In which case Edge might wait for the endpoint to return a completion status, thereby blocking your API anyway. For this the backend has to architected so that it will return back a 202 status (say) and process the job asynchronously.

If the backend doesn't support asynchronous, you could have a Node.js target endpoint and make an asynchronous call from there so as to get the asynchronous behaviour you desire.

3. Finally, what is the client that is making the call? If that client itself can support asynchronous like a browser or Node.js app (say), then you can as well use the JS callback feature to create this asynchronous behaviour without touching the API or the BE.