Wednesday, January 27, 2010

Remote services using REST

In this example, we implement a REST client and a REST server.

Components used in this example
Implementation of the client

class MyRestClient
Processing the user request
  • We get the data and the action.
  • We parse the data to get a scalar or an array.
  • We set the server name. It is the same as the client plus one parameter to indicate it is the server.
  • We get the list of remote methods. We remove the system methods.
  • We process the request.
  • If there is a XML node named response, we get the response that is a scalar.
  • Otherwise we extract the array from the XML node.
  • We add the response details if needed.
  • If we catch an exception, we return the error message.

    public function process()
// We get the data and the action.
list($data$action$response) = $this->_getParameters();

$methods = array();
        try {
// We parse the data to get a scalar or an array.
$parsed $this->_parseData($data);
// We set the server name.
            // It is the same as the client plus one parameter to indicate it is the server.
$server "http://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}?server=";
$client = new Zend_Rest_Client($server);

// We get the list of remote methods. We remove the system methods.
$get $client->getFunctions()->get();
$methods $this->_toArray($get->getFunctions);
$methods preg_grep('~^(array|scalar)_\w+$~'$methods);
// We process the request.
if ($action) {
$get $client->$action($parsed)->get();
                if (
$get->getStatus()) {
                    if (isset(
$get->response)) {
// If there is a XML node named response, 
                        // we get the response that is a scalar. 
$result['GET'] = (string)$get;
                    } else {
// Otherwise we extract the array from the XML node.
$result['GET'] = $this->_toArray($get->$action);
                } else {
$result['ERROR'] = (string)$get;                        

// We add the response details if needed.
$response and $result['RESPONSE'] = $get;
            } else {
$result 'Enter some data and select an action.';
        } catch (
Exception $e) {
// If we catch an exception, we return the error message.
$result '[' __CLASS__ '] ' $e->getMessage();

        return array(
Extraction of the parameters from the GET request

    private function _getParameters()
$data = isset($_GET['data'])? $_GET['data'] : '';
$action = isset($_GET['action'])? $_GET['action'] : null;
$response = empty($_GET)? : !empty($_GET['response']);

        return array(
Extraction of the data into a scalar or an array.

    private function _parseData($data)
        if (
strpos($data"\n") === false) {
        } else {
explode("\n"$data) as $line) {
$parts explode('='$line2);
                if (
count($parts) == 1) {
$parsed[] = trim($parts[0]);
                } else {
$parsed[trim($parts[0])] = trim($parts[1]);
Extraction of the array from the XML node
  • We ignore the status that is returned as an array element.
  • We explore nodes recursively.
  • We replace the keys generated by ZF Server with the corresponding index.
  • Or we keep the key as it is.

    private function _toArray($simpleXml)
$array = array();
$simpleXml as $key => $value) {
// We ignore the status that is returned as an array element.
if (!($key == 'status' and strtolower($value) == 'success')) {
// We explore nodes recursively.
$value instanceof SimpleXMLElement and $value $this->_toArray($value);
                if (
preg_match('~^key_(\d+)$~'$key$match)) {
// We replace the keys generated by ZF Server with the corresponding index.
$array[$match[1]] = $value;
                } else {
// Or we keep the key as it is.
$array[$key] = $value;


No comments:

Post a Comment