source code bean

07 Jan, 2010

Creating a JSON-RPC service using Zend Json Server

Posted by: Peter In: PHP|Web|Zend Framework

In this post I am going to show how easy it is to create a JSON-RPC web service using the built in support in Zend Framework.

First we need to create the php-file that will handle the incoming RPC calls. It is not advised to put this inside the MVC structure of a Zend web application, since that will lead to unessesary complexity and overhead. The Zend people recommend that we create the JSON-RPC under /public/api/vX/, so lets create the file /public/api/v1/jsonrpc.php (if you haven’t setup your Zend MVC structure, read my blog post Getting started with the zend framework to get started).


We will have to do the regular bootstrapping to get our application up and running:

  1.  
  2. // Define path to application directory
  3. defined(‘APPLICATION_PATH’)
  4.     || define(‘APPLICATION_PATH’, realpath(dirname(__FILE__) . ‘/../../../application’));
  5.  
  6. // Define application environment
  7. defined(‘APPLICATION_ENV’)
  8.     || define(‘APPLICATION_ENV’, (getenv(‘APPLICATION_ENV’) ? getenv(‘APPLICATION_ENV’) : ‘production’));
  9.  
  10. // Ensure library/ is on include_path
  11. set_include_path(implode(PATH_SEPARATOR, array(
  12.     realpath(‘../../../library’),
  13. )));
  14.  
  15. /** Zend_Application */
  16. require_once ‘Zend/Application.php’;
  17.  
  18. // Create application, bootstrap, and run
  19. $application = new Zend_Application(
  20.     APPLICATION_ENV,
  21.     APPLICATION_PATH . ‘/configs/application.ini’
  22. );
  23.  
  24. $application->bootstrap();
  25.  

The next step is to create the class that will be exposed through the service. I will create a very simple class that will simply perform an addition of two ints. It is very important to describe the input parameters using the @param directive in the comment. This information is used by the Json Server when creating the SMD (Service Mapping Description).

  1.  
  2. /**
  3.  * Simple – sample class to expose via JSON-RPC
  4.  */
  5. class Simple
  6. {
  7.     /**
  8.      * Return sum of two variables
  9.      *
  10.      * @param  int $x
  11.      * @param  int $y
  12.      * @return array
  13.      */
  14.     public function add($x, $y)
  15.     {
  16.         return array(‘result’ => $x + $y);
  17.     }
  18. }
  19.  

The last step to get the JSON-RPC server running:

  1.  
  2. // Instantiate server, etc.
  3. $server = new Zend_Json_Server();
  4. $server->setClass(‘Simple’);
  5.  
  6.  
  7. if (‘GET’ == $_SERVER[‘REQUEST_METHOD’]) {
  8.     // Indicate the URL endpoint, and the JSON-RPC version used:
  9.     $server->setTarget(‘/api/v1/jsonrpc.php’)
  10.            ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);
  11.  
  12.     // Grab the SMD
  13.     $smd = $server->getServiceMap();
  14.  
  15.     // Return the SMD to the client
  16.     header(‘Content-Type: application/json’);
  17.     echo $smd;
  18.     return;
  19. }
  20.  
  21. $server->handle();
  22.  

Now your JSON-RPC Server should be up running. Browsing http://{your web server}/api/v1/jsonrpc.php should result in the following SMD:

  1.  
  2. {
  3.   "transport":"POST",
  4.   "envelope":"JSON-RPC-2.0",
  5.   "contentType":"application\/json",
  6.   "SMDVersion":"2.0",
  7.   "target":"\/api\/v1\/jsonrpc.php",
  8.   "services": {
  9.       "add":{
  10.           "envelope":"JSON-RPC-2.0",
  11.           "transport":"POST",
  12.           "parameters":[
  13.               {"type":"integer","name":"x","optional":false},
  14.               {"type":"integer","name":"y","optional":false}],
  15.           "returns":"array"
  16.        }
  17.     },
  18.    "methods":{
  19.        "add":{
  20.            "envelope":"JSON-RPC-2.0",
  21.            "transport":"POST",
  22.            "parameters":[
  23.                {"type":"integer","name":"x","optional":false},
  24.                {"type":"integer","name":"y","optional":false}],
  25.            "returns":"array"}
  26.        }
  27. }
  28.  

jQuery does not support calling JSON-RPC services out of the box, but fourtenly there is plenty of plugins for jquery that fixes this. One is the JSON-RPC client found here. Download the client and put the javascript files into your /js folder. Then create a new file test.html and add the following html:

  1.  
  2. <html>
  3. <head>
  4.         <script LANGUAGE="javascript" SRC="js/jquery-1.3.min.js"></script>
  5.         <script LANGUAGE="javascript" SRC="js/json2.js"></script>
  6.         <script LANGUAGE="javascript" SRC="js/jquery.zend.jsonrpc.js"></script>
  7.         <script>
  8.                 $(document).ready(function(){
  9.                         test = jQuery.Zend.jsonrpc({url: ‘/api/v1/jsonrpc.php’});
  10.                         alert(test.add(1,1)['result']);
  11.                 });
  12.         </script>
  13. </head>
  14. <body>
  15. </body>
  16. </html>
  17.  

We are all done! Browsing test.html should result in an alert box containg the result.
result

Congratulations! You have created a JSON-RPC service!



Read more about the Zend Framework:



6 Responses to "Creating a JSON-RPC service using Zend Json Server"

1 | udara

May 3rd, 2010 at 3:08 am

Avatar

test.add(1,1)['result'],in this code u send two integer arguments to add() method.How to send a complicated object as a argument.
i mean
var ob=new Object();
ob.name=”udara”;
how can i send ob as a argument.
for the momnet im doing JSON.stringify(ob) andsent json string as a argument.

2 | Creating a JSON-RPC server with Zend Framework

May 21st, 2010 at 2:23 am

Avatar

[...] found this blog very helpful in figuring out how to do this. The first step is to create a new bootstrap file. I [...]

3 | developing a maintainable RPC system | DeveloperQuestion.com

November 22nd, 2010 at 7:15 pm

Avatar

[...] I have seen numerous blog posts and tutorials on how to use ZF's JSON-RPC server (see here and here), but they all seemed geared towards exposing a small, publicly consumable API. Code duplication is [...]

4 | Fordnox

March 25th, 2011 at 7:46 am

Avatar

What about authentication for webservice? How would you implement it?

5 | Jeremy Glover

November 5th, 2011 at 2:13 pm

Avatar

I’m also curious about how you would implement authentication via API keys. Thoughts?

6 | Steve

January 23rd, 2012 at 10:01 pm

Avatar

Hi,

Where does the simple.php class reside in the application structure?

I’ve tried putting it in the library folder but I get this error:

( ! ) Fatal error: Uncaught exception ‘Zend_Server_Reflection_Exception’ with message ‘Invalid class or object passed to attachClass()’ in C:\Zend_Framework\library\Zend\Server\Reflection.php on line 68
( ! ) Zend_Server_Reflection_Exception: Invalid class or object passed to attachClass() in C:\Zend_Framework\library\Zend\Server\Reflection.php on line 68

Thanks,
Steve

Comment Form

Adwords

About

Welcome to source code bean! On this site I post stuff that I encounter in my job and spare time. The content is mostly related to .NET development, but my interest in techonology is very broad, so often you will find posts on totally different subjects!