JSON and XML APIs - Asynchronous API Responses

JSON and XML APIs - Asynchronous API Responses

Some API requests, such as media library updates and log archivals, may take an inordinately long time to complete. These requests are normally processed synchronously -- that is, the API client must remain connected until the request completes in order to receive the response -- which may be undesirable in interactive environments where a user must wait for the operation to complete.

To better handle such cases, Centova Cast provides an asychronous response mechanism through which the API client can submit the request, disconnect, and then receive the results of the API call via a postback to a client-supplied URL.

Submitting a Request for Asynchronous Processing

Asynchronous requests are mostly identical to synchronous requests, so it is important to understand how to submit standard API requests before implementing asynchronous processing in your API client.

Asynchronous requests are handled in a process of three steps:

  1. Request

    The API client initiates a normal request to the XML or JSON API, but provides a callback URL via the callbackurl parameter.

    For example, a request to following JSON API endpoint would normally request the status for the user account named jdoe:

     http://example.com:2199/api.php?xm=server.getstatus&f=json&a[username]=jdoe&a[password]=secret
    

    To submit this request for asynchronous processing, simply append a callbackurl parameter:

     http://example.com:2199/api.php?xm=server.getstatus&f=json&a[username]=jdoe&a[password]=secret&callbackurl=http://example.com/myhandler.php
    
  2. Initial Response

    The API server will immediately respond to the API request to confirm that it was submitted successfully:

    {
        "type":"success",
        "response":{
            "data":[
                {
                    "callbackurl"=>"http://example.com/myhandler.php"
                }
            ],
            "message":"Asynchronous request started"
        }
    }
    

    Alternately, the API server may return an error if there was a problem authenticating the request, or if the requested API method was not valid.

    Unlike a response to a synchronous request, this response does not indicate the results of the call to the API method itself; this response only indicates whether or not the request was successfully submitted for processing.

    After sending this initial response, Centova Cast closes the connection to the API client.

  3. Callback

    The API server continues to process the request asynchronously. The results of the call to the API method will be posted to the callback URL (in this example, http://example.com/myhandler.php) when processing is completed.

While asynchronous processing is typically only useful for long-running API calls, it is possible to submit any JSON or XML API method call for asynchronous processing via the callback mechanism.

Handling the Response Callback

Centova Cast submits the response to the callback URL as an HTTP POST request wherein the API response content is provided as POST data.

The API response content provided to the callback is identical to that which would have been received through a synchronous API call. When making an asynchronous request to the JSON API, the callback will receive a JSON-encoded response; when accessing the XML API, the callback will receive an XML-encoded response.

The HTTP response code and/or output from the callback script is ignored by Centova Cast, except for the purpose of logging non-2xx response codes to the Centova Cast event log.

JSON API Response Callback Example

When submitting the following request to the JSON API:

http://example.com:2199/api.php?xm=server.getstatus&f=json&a[username]=jdoe&a[password]=secret&callbackurl=http://example.com/myhandler.php

The handler at http://example.com/myhandler.php will receive the following postback from Centova Cast:

POST /myhandler.php HTTP/1.0
Host: example.com
User-Agent: Centova Cast/3.x.x
Connection: close
Content-Length: 312
Content-Type: application/json

{
    "type":"success",
    "response":{
        "data":[
            {
                "username":"jdoe",
                "state":"up",
                "expected":"up",
                "sourcestate":"up",
                "sourceexpected":"up"
            }
        ],
        "message":"Check complete"
    }
}

Your custom myhandler.php script might handle the callback as follows:

<?php
$json = file_get_contents('php://input');
$result = json_decode($json);
record_response(
    'Received a response of type ' . $result->type . ' containing data: ' .
    print_r($result->response->data,true)
);

function record_response(/* ... */) {
    // do something appropriate with the response
}

XML Response Callback Example

When submitting the following request to the XML API:

<?xml version="1.0" encoding="UTF-8"?>
<centovacast>
    <request class="system" method="info">
        <password>secret</password>
        <username>jdoe</username>
        <callbackurl>http://example.com/myhandler.php</callbackurl>
    </request>
</centovacast>

The handler at http://example.com/myhandler.php will receive the following postback from Centova Cast:

POST /myhandler.php HTTP/1.0
Host: example.com
User-Agent: Centova Cast/3.x.x
Connection: close
Content-Length: 478
Content-Type: text/xml

<?xml version="1.0" encoding="UTF-8"?>
<centovacast version="3.x.x" host="example.com:2199">
    <response type="success">
        <message>Check complete</message>
        <data>
            <row>
                <username>jdoe</username>
                <state>up</state>
                <expected>up</expected>
                <sourcestate>up</sourcestate>
                <sourceexpected>up</sourceexpected>
            </row>
        </data>
    </response>
</centovacast>

Your custom myhandler.php script might handle the callback as follows:

<?php
$xml = file_get_contents('php://input');
$result = simplexml_load_string($xml);
record_response(
    'Received a response of type ' . $result->response['type'] . ' containing data: ' .
    print_r($result->response->data,true)
);

function record_response(/* ... */) {
    // do something appropriate with the response
}

API Errors

The results of an unsuccessful API call are posted to the callback URL in exactly the same manner as a successful API result, and may be handled in exactly the same manner as an error received from a synchronous API call.

Postback Failures

Centova Cast will attempt to submit the API result to the callback URL precisely once. It will neither queue nor retry a failed postback; in the event of a failure, the result data will be lost.

Failed postbacks are, however, logged to the Centova Cast event log which may be accessed by the administrator of the Centova Cast server.