Zend Server WebAPI spotlight: Asynchronous Actions

December 26, 2013

Articles

Hey Everybody,

Today we’ll discuss WebAPI asynchronous actions – requests that respond immediately but have not actually completed yet.

In the previous Spotlight, we took a look at the basic steps of connecting to and using the Zend Server WebAPI. Many of the available WebAPI actions, will return immediate and final responses. These responses may not be immutable, as the system’s state could change but they will be correct and describe the system elements in an up-to-date state.

Most of these synchronous Zend Server WebAPI actions are “read” actions – actions which do not actually modify anything. Unlike these benign actions, WebAPI provides some actions that will take time to complete. These actions can be complex, or perhaps rely on some external entity such as a remote server and so may take an unforeseen amount of time.

202 “Accepted” status for Asynchronous actions

Having an API which takes its time to respond is unacceptable – timeouts, system resources, open files, all of these cannot wait for a foreign API to “do its thing” at leisure. In our world of API-first applications, we expect our APIs to be quick and not delay the rest of the system. In the Zend Server WebAPI we try to keep with a concept we dubbed “Immediate Responsiveness”. The WebAPI will attempt to return a timely response with complete information – or as complete as we can get it to be. In this delicate balance of “Available data” and “Responsiveness”, Responsiveness will usually win in Zend Server.

To this end, some of our actions, particularly those that make system changes, are asynchornous and will return a “202 Accepted” http status code.

The 202 status code means (from https://tools.ietf.org/html/rfc2616#section-10.2.3)

The request has been accepted for processing, but the processing has not been completed…

In the WebAPI’s context, it means Zend Server has accepted the requested action and will act upon it. The response code is noted for every webapi action in the WebAPI reference, most actions will consistently return either a 200 or 202.

Behind the scenes, your asynchronous action registered a task with Zend Server’s internal queue manager and this task will usually start processing within a second of the request. In the meantime, your original request has already returned, effectively returning execution control back to your system, freeing it to carry on with its own logic.

Sequence diagram of polling webapi asynchronous operation, click to enlarge

Sequence diagram of polling an asynchronous operation

Most simple scenarios would end here – the action will execute asynchronously, make its changes and your work will have been completed. In some cases, particularly when changing configuration or some complex activities, you will be interested in knowing when said action has actually finished execution. This sort of ongoing-polling can be done by using a variety of WebAPI actions but only one will tell you if the task you’ve sent has actually completed: the tasksComplete WebAPI action.

Lets have us an example

Your system, a webhosting control system, has a user controlled feature that allows the user to add new vhosts to his Zend Server host machine.

The sequence diagram to the right describes the way this can be implemented using Zend Server. The diagram emphasises polling for an asynchronous action’s completion. The code below illustrates how the diagram could be implemented.

Adding a new vhost can be done using the vhostAdd WebAPI action:

$client = new \Zend\Http\Client();
$client->setUri('http://localhost:10081/ZendServer/Api/vhostAdd')
 ->setEncType(\Zend\Http\Client::ENC_FORMDATA)
 ->setMethod('POST') /// because all "modify" webapi actions are POST
 ->setHeaders(array(
   ...
 ))
 ->getRequest()->getPost()->fromArray(
     array('name' => 'mynewvhost', 'port' => '80'));

$response = $client->send();
echo $response->getBody();

Which should respond with:

{"zendServerAPIResponse": "http://www.zend.com/server/api/...",
 "requestData": {"apiKeyName": "Unknown","method": "vhostAdd"},
 "responseData": {"vhostList": [
  {"id": "10", ... and more details about the vhost ... }]}
}
Note that all WebAPI actions are also tracked in the Zend Server Audit Trail

After the vhostAdd WebAPI action has responded with its 202, your system may now start polling of the tasksComplete action. This action will return a true value only once Zend Server has “settled down” again, following the hubub of changing its configuration.

Polling tasksComplete:

$client->setUri('http://localhost:10081/ZendServer/Api/tasksComplete')
 ->setMethod('GET')
 ->setHeaders(array(
   ...
 )); /// no query parameters needed

$response = $client->send();
echo $response->getBody();

Which should (eventually) respond with:

{"zendServerAPIResponse": "http://www.zend.com/server/api/...",
 "requestData": {"apiKeyName": "Unknown","method": "tasksComplete"},
 "responseData": {"tasksComplete":true,...}}

Once your system receives this confirmation, you may now use the restartPhp WebAPI action to seal the deal and make the new vhost available online. Note that restartPhp is also in-itself asynchronous and can also be tracked using tasksComplete.

Summary

In this article-length post, I’ve gone over the basic practices of using asynchronous WebAPI actions, the implications of using them and the options they provide you. Be sure to post any questions or let me know what topics within the WebAPI interest you.

,

About YonmaN

Yonni Guido Mendes is a seasoned developer and integration expert who's been writing PHP for the past 12 years. He's worked on websites, billing, external integration and user interfaces on different platforms and in varying methodologies. Yonni is also a father, a gamer and a technophile.

View all posts by YonmaN

One Response to “Zend Server WebAPI spotlight: Asynchronous Actions”

  1. YonmaN Says:

    You can see this mechanism in action in Zend Server’s Web API samples package: https://github.com/YonmaN/SamplesWebAPI

Leave a Reply

You must be logged in to post a comment.