zend-framework

Zend Framework - How to create an API that is accessible both externally and internally?


I'm looking to create a web site and will be creating a mobile app at a later date.

I want to be able to offer the same level of data (i.e. a listing of books) to both the web site and the app. I'd like to use an API for this but am struggling to find any examples or decent articles online.

So I suppose my question is, if I were to create a JSON 'endpoint' accessible by a mobile app over HTTP (e.g. http://www.example.com/api/v1.0/json) how do access the same functionality internally from my Zend Application?

(obviously I don't want to duplicate the database interaction 'model' steps)


Solution

  • Since Zend is really not RESTful, unfortunately, your best bet is JSON-Rpc.

    You can do it in a controller, or you can just make an ajax.php in addition to your index.php to reduce overhead like this guy did here

    Basically, all you need to do is this:

    $server = new Zend_Json_Server();
    $server->setClass('My_Class_With_Public_Methods');
    // I've found that a lot of clients only support 2.0
    $server->getRequest()->setVersion("2.0");
    if ('GET' == $_SERVER['REQUEST_METHOD']) {
        // Indicate the URL endpoint, and the JSON-RPC version used:
        $server->setTarget('/ajax.php')
               ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);
    
        // Grab the SMD
        $smd = $server->getServiceMap();
    
        // Return the SMD to the client
        header('Content-Type: application/json');
        echo $smd;
        return;
    }
    
    $server->handle();
    

    then somewhere in your layout:

    $server = new Zend_Json_Server();
    $server->setClass('My_Class_With_Public_Methods');
    $smd = $server->getServiceMap();
    ?>
    <script>
    $(document).ready(function() {
        rpc = jQuery.Zend.jsonrpc({
            url : <?=json_encode($this->baseUrl('/ajax'))?>
            , smd : <?=$smd?>
            , async : true
        });
    });
    </script>
    

    for the sake of example, here's that class:

    class My_Class_With_Public_Methods {
        /**
          * Be sure to properly phpdoc your methods,
          * the rpc clients like it when you do
          * 
          * @param float $param1
          * @param float $param2
          * @return float
          */
        public function someMethodInThatClass ($param1, $param2) {
            return $param1 + $param2;
        }
    }
    

    then you can simply call methods like so in javascript:

    rpc.someMethodInThatClass(first_param, second_param, {
        // if async = true when you setup rpc,
        // then the last param is an object w/ callbacks
        'success' : function(data) {
    
        }
        'error' : function(data) {
    
        }
    });
    

    There aren't a lot of well known JSON-rpc libraries for Android / iPhone - but I have found that this works with Zend_Json_Server for Android:

    http://software.dzhuvinov.com/json-rpc-2.0-base.html

    and this works for iPhone:

    http://www.dizzey.com/development/ios/calling-json-rpc-webservice-in-ios/

    From here, obviously, you can use My_Class_With_Public_Methods in the same way that javascript / your mobile app does.