A web developer's blog. PHP, MySQL, CakePHP, Zend Framework, Wordpress, Code Igniter, Django, Python, CSS, Javascript, jQuery, Knockout.js, and other web development topics.

Problems with Zend_Rest. Any ideas? FIXED!

I am stuck with my problem. I am not sure if it is the way I have things set up or it is something else.This works!

$rest = new Zend_Rest_Client('http://mysite.com/api/emp/method/getById/id/1124921/apikey/1234');
$result = $rest->get();
if($result->status()=='success') {
    echo $result->emp_id() .' '. $result->emp_shortname().' '. $result->status();
} else {
    echo $result->response().' '.$result->status();
}

But this doesn’t:

$rest = new Zend_Rest_Client('http://mysite.com/api/emp');
$rest->method('getById');
$rest->id('1124921');
$rest->apikey('1234');
$result = $rest->get();
if($result->status()=='success') {
    echo $result->emp_id() .' '. $result->emp_shortname().' '. $result->status();
} else {
    echo $result->response().' '.$result->status();
}

The Zend_Rest_Client has this code:

require_once APPLICATION_PATH.'/models/Employee.php';
require_once APPLICATION_PATH.'/models/Api.php';
class EmprestServer
{    
/**     
* /api/emp/id/1124921     
*     
* @param unknown_type $emp_id     
* @return unknown     
*/    
public function getById($id,$apikey)    
{
        $emp = new Employee();
        $data = array();
        if(!$this->checkKey($apikey)) {
            throw new Exception('Key is invalid.');
        }
        if(!$data = $emp->getEmployeeById($id)) throw new Exception('Employee ID not found.');
        $data = $data->toArray();
        return $data;
}    
 
/**     
*     
* @param unknown_type $emp_shortname     
* @return unknown     
*/    
public function getByShortname($shortname,$apikey)    
{        
    //return $this->getData(array('shortname'=>$shortname));
    $emp = new Employee();
    $data = array();        
    //if(!$this->checkKey($apikey)) {
    if($apikey != '1234') {
        throw new Exception('Key is invalid.');
    }        
    if(!$data = $emp->getEmployeeByShortname($shortname)) throw new Exception('Employee ID not found.');
    $data = $data->toArray();
    return $data;    
}    
 
private function checkKey($apikey)    
{
    $api = new Api();
    $result = $api->verifyApiKey($apikey);
    if($result) {
        return $result;
    }
    else {
        return false;
    }
}
}

The problem is, $apikey does not get passed to the Emprest Class. When I var_dump $apikey, I am shown the methodName (getById or getByShortname)… So I always get the exception. Any ideas?

UPDATE: I read the manual(section 44.2.3. Request Arguments) until my eyes and nose bled. And I quote:

$client = new Zend_Rest_Client('http://example.org/rest');
 
$client->arg('value1');
$client->arg2('value2');
$client->get();
 
// or
 
$client->arg('value1')->arg2('value2')->get();

Both of the methods in the example above, will result in the following get args:

?method=arg&arg1=value1&arg=value1&arg2=value2

You will notice that the first call of

$client->arg('value1');

resulted in both

method=arg&arg1=value1 and arg=value1;

this is so that Zend_Rest_Server can understand the request properly, rather than requiring pre-existing knowledge of the service.

I left the code at work so I will be looking more into this as soon as I can.

UPDATE 2
I got it working. I made some updates.
The Zend_Rest_Client part will have something like this:

$rest = new Zend_Rest_Client('http://example.org/api/emp');
$rest->getById(); //this was not here before. This made it work!
$rest->id('1124921');
$rest->apikey('1234');
$result = $rest->get();
if($result->status()=='success') {
    echo $result->emp_id() .' '. $result->emp_shortname().' '. $result->status();
} else {
    echo $result->response().' '.$result->status();
}

Then the empAction has this:

    public function empAction()
    {
        $params = $this->_getAllParams();
 
        unset($params['controller']);
        unset($params['action']);
        unset($params['module']);
 
        $filter_params = $params; //need to filter this
 
        $param_keys = array_keys($params);
 
        foreach($param_keys AS $key) {
            $request[$key] = $filter_params[$key]; //need to filter key
            if(!$request[$key]) { //need better checking
                throw new Exception($request[$key].' contained invalid data.');
            }
        }
 
        require_once 'EmprestServer.php';
        $server = new Zend_Rest_Server();
        $server->setClass('EmprestServer');
        $server->handle($request);
    }

Now, I can get the $apikey in my Rest server:

class EmprestServer
{
 
    /**
     * /api/emp/id/1124921
     *
     * @param unknown_type $emp_id
     * @return unknown
     */
    public function getById($id,$apikey)
    {
        $emp = new Employee();
        $data = array();
 
        if(!$this->checkKey($apikey)) {
            throw new Exception('Key is invalid.');
        }
 
        if(!$data = $emp->getEmployeeById($id)) throw new Exception('Employee ID not found.');
        $data = $data->toArray();
 
        return $data;
    }
//rest of the code here.
}

UPDATE 3
To add another parameter make sure that your docblock corresponds to the number of parameters found in your Rest Server. You will now have 3 parameters passed. If you have problems, more details on this can be found here.

Here is an example:

$rest = new Zend_Rest_Client('http://example.org/api/emp');
$rest->getByShortname();
$rest->shortname('wdelrosa');
$rest->apikey('1234');
$rest->var1('1234');
$result = $rest->get();
 
if($result->status()=='success') {
    echo $result->emp_id() .' '. $result->emp_shortname().' '. $result->status();
} else {
    echo $result->response().' '.$result->status();
}

The Rest Server would have this:

    /**
     * Enter description here...
     *
     * @param unknown_type $shortname
     * @param unknown_type $apikey
     * @param unknown_type $var1
     * @return unknown
     */
    public function getByShortname($shortname,$apikey,$var1)
    {
        //return $this->getData(array('shortname'=>$shortname));
        $emp = new Employee();
        $data = array();
 
        if(!$this->checkKey($apikey)) {
        //if($apikey == '1234') {
            throw new Exception('Key is invalid.');
        }
 
        if(!$data = $emp->getEmployeeByShortname($shortname)) throw new Exception('Employee ID not found.');
 
        $data = $data->toArray();
        return $data;
    }
This entry was posted in General and tagged , , , . Bookmark the permalink.

5 Responses to Problems with Zend_Rest. Any ideas? FIXED!

  1. Macro says:

    Now your request variables looks like:
    ?method=method&arg1=getById&getById=getById&id=1124921&apikey=1234
    So client is calling to wrong method.

    My sugestion:
    $rest->getById(array(‘id’ => 1124921, ‘apikey’ =>1234));

    References:
    http://framework.zend.com/manual/en/zend.rest.client.html
    arbd Zend_Rest_Client class function _call() source

  2. Wenbert says:

    @Marco
    Can you briefly explain how you came up with:

    ?method=method&arg1=getById&getById=getById&id=1124921&apikey=1234
    

    The $rest->getById(array(’id’ => 1124921, ‘apikey’ =>1234)); suggestions looks good, but I am still wondering how to go about with the $rest->apikey example.

    What do you mean by this?

    arbd Zend_Rest_Client class function _call() source
    
  3. Macro says:

    In Zend_Rest_Client class (path is ZFlibrary/Zend/Rest/Client.php) we have a function:

        public function __call($method, $args)
        {
            $methods = array('post', 'get', 'delete', 'put');
    
            if (in_array(strtolower($method), $methods)) {
              ... // not our case
            } else {
                if (sizeof($args) == 1) {
                    // Uses first called function name as method name
                    if (!isset($this->_data['method'])) {
                        $this->_data['method'] = $method;
                        $this->_data['arg1']  = $args[0];
                    }
                    $this->_data[$method]  = $args[0];
                } else {
                    // Solution
                    $this->_data['method'] = $method;
                    if (sizeof($args) > 0) {
                        foreach ($args as $key => $arg) {
                            $key = 'arg' . $key;
                            $this->_data[$key] = $arg;
                        }
                    }
                }
                return $this;
            }
        }
    

    Here are described how it works when you are calling
    $row->getById(‘getById’);
    Result from __call() function is that
    $this->_data even to array(‘method’ => ‘getById’, ‘arg1′ => ‘getById’, ‘getById’ => ‘getById’) which is equal to query string: ?method=method&arg1=getById&getById=getById

    Later when you are calling to __call() with:
    $rest->id(’1124921′);

    you just get result even to $this->_data['id'] = ’1124921′, because that key $this->_data['method'] is already set.

    Also how is query string created is explained in $rest->apikey example from Zend manual. Unfortunately from that example you can’t get solution for your problem. Therefor I had checked for solution in __call() function source code.
    When you are calling like
    $rest->getById(array(’id’ => 1124921, ‘apikey’ =>1234));
    source code part under comment ‘// solution’ will be executed and will give result which you looking for.

  4. Wenbert says:

    @Marco

    Thank you. I managed to make it work. I am updating the code after I make this comment.

  5. Pingback: Zend Framework: Handling custom XML reponses using Zend_Rest_Server | eKini: Web Developer Blog

Leave a Reply to Macro Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>