How to decide if an API should be synchronous or asynchronous

api-design

I am developing a service which will expose some APIs through REST end-point.
I have some API which can take a lot of time like say 5 to 10 minutes to complete the requested operation.

I am also writing the client side application which is multi-threaded and it can make multiple requests to server at the same time. If the server API happens to be synchronous, it is still fine for that particular client thread to hang waiting for the response from server. So, the client is not completely stuck, it can continue with other operations.

I understand that if I make it asynchronous, I have to do some more work for API operation status management, providing way for client to get the operation status.

Having said that, I am still not able to decide whether I should make this server API synchronous or asynchronous.

On what basis does one decide to make a API synchronous or asynchronous?
Does it depend on how long the API operation will take?
Does it depend on whether client can handle blocking call?

Best Answer

HTTP is synchronous in the sense that every request gets a response, but asynchronous in the sense that requests take a long time and that multiple requests might be processed in parallel. Therefore, many HTTP clients and servers are implemented in an asynchronous fashion, but without offering an asynchronous API. Using multiple threads is one way to implement asynchronicity, but there are others like callbacks or event loops.

If you want an asynchronous API with HTTP in the sense that a response is not immediately available, you will have to model the asynchronicity explicitly:

  • When a valid request is received, the server immediately responds with a success status, most likely 202 Accepted or 303 See Other.
  • The backend then works on the job in the background (maybe as a separate thread, maybe as a separate server).
  • The response should describe how the status of the job can be monitored and how the result can be fetched. Later, the client can use this information to retrieve the result.

There are a couple of techniques like long-polling or chunked transfer to push the result as soon as it is available from that resource, but generally requires client cooperation.

The alternative is to use a different protocol than HTTP, in particular a protocol where messages don't need a response. Within the web stack, WebSockets are such a protocol and allow the server to push a response at a later time. However, using such protocols implies a heavier development effort for you because non-HTTP APIs lack tooling and framework support.

Because async APIs are more complicated for everyone involved, they should be avoided. Again, they are not necessary for having async clients or servers. Modelling asynchronicity in your API is appropriate when:

  • the request launches a background job that may or may not be processed quickly, or
  • creating the response inherently takes some time, or
  • you cannot guarantee that a response will be ready before the client times out, probably on the order of 10 to 30 seconds.

For example, the web interface of my WiFi router can reboot the router. This inherently takes some time. They have implemented this in the following asynchronous fashion:

  1. I request a reboot.
  2. The server responds immediately with a status page.
  3. The router initiates the reboot.
  4. The status page continuously requests the status in the background. Most of the time, the request will time out because the server has not yet restarted.
  5. The router reboots and the server comes back online.
  6. On the next status request, the server delivers a status response that the rebooting has completed, and redirects my browser to a new page.
Related Topic