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″]