For my latest project, I was determined to avoid confusing Ajax requests by implementing my own JSON-RPC. Again, Zend Framework has made this incredibly easy.

The documentation recommends not running your Ajax request through the MVC. At first I was a little concerned, but it makes sense as the MVC does add a lot of unnecessary overhead.

I found this blog very helpful in figuring out how to do this.
The first step is to create a new bootstrap file.
I created one in public/api/1.0/jsonrpc.php

Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath('../../../library'),
    get_include_path(),
)));

/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);

$application->getBootstrap()
            ->bootstrap('doctrine')
            ->bootstrap('config');

// Instantiate server, etc.
$server = new Zend_Json_Server();
$server->setClass('App_Model_JsonRpc');

if ('GET' == $_SERVER['REQUEST_METHOD']) {
    // Indicate the URL endpoint, and the JSON-RPC version used:
    $server->setTarget('/api/1.0/jsonrpc.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();

You may want to modify the $application->getBootstrap() line and add/remove bootstrap methods depending on your requirements. I need access to my database within my JSON-RPC server and use Doctrine as my ORM so I bootstrap that.

The most important line is:

$server->setClass('App_Model_JsonRpc');

This tells the server what class should handle all the JSON requests.

I also added a RedirectRule in my .htaccess file to hide the php extension. It’s unnecessary but the .php extension isn’t seen anywhere else on my site so I don’t want it on my JSON RPC server either.
I added this line…

RewriteRule ^api/([0-9].[0-9])/jsonrpc$ /api/$1/jsonrpc.php [NC,L]

…between these two lines:

RewriteRule ^.*$ - [NC,L]
RewriteRule ^api/([0-9].[0-9])/jsonrpc$ /api/$1/jsonrpc.php [NC,L]
RewriteRule ^.*$ index.php [NC,L]

[ad name=”Google Adsense 468×60″]
I then created a class called App_Model_JsonRpc and put it in my models directory.
/application/models/JsonRpc.php

class App_Model_JsonRpc
{

    /**
     * Return sum of two variables
     *
     * @param  int $x
     * @param  int $y
     * @return array
     */
    public function add($x, $y)
    {
        return  $x + $y;
    }
}

The doc blocks are very important as Zend_Json_Server generates the SMD based on the contents of the Doc block.

That’s it for the server. Send it the proper JSON code and it will add 2 numbers together and return the result.

Heres a quick example of how to use your new server.
I recommend installing the ZendJsonRpc jQuery plugin as it makes talking to your server much easier. You can download the plugin here.

<script src="/js/json2.js" type="text/javascript"></script>
<script src="/js/jquery.zend.jsonrpc.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
 myApi = jQuery.Zend.jsonrpc({url: '/api/1.0/jsonrpc'});

 alert('5+5=' + myApi.add(5,5));

 });
</script>

That’s it!
[ad name=”Google Adsense 468×60″]

Share