Zend JSON Server

I implemented Zend JSON RPC Server today. The documentation on the Zend website left a lot of room for guesswork and none of the online resources I could find provided the complete picture. Here a step by step guide on how to set it up.

Most users probably use this API to perform JS calls from their front-end to their own back-end. For this use case you need 3 components.

  • An API controller
  • A class to handle the API calls
  • and some JS code to perform the call

The API controller (application/controllers/ApiController.php):

<?php
/*
 * Controller for JSON API calls
 *
 * API methods are defined in library/Test/Api.php
 */
class ApiController extends Zend_Controller_Action
{
    private $server;
    
    /*
     * Initilaize
     */
    public function init()
    {
        // Initialize Zend_Json_Server
        $this->server = new Zend_Json_Server();
        $this->server->setClass('Test_Api');

        // Disable layout
        $this->_helper->layout->disableLayout();
    }

    /*
     * Handle the API request
     */
    public function indexAction()
    {
        $request = $this->getRequest();

        // Return the service mapping description for GET requests
        if ($request->isGet()) {
            $controller = $request->getControllerName();
            $module = $request->getModuleName();

            // Set the API url and envelope
            $this->server
                ->setTarget('/' . $module . '/' . $controller)
                ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);
         
            // Return the SMD to the client
            header('Content-Type: application/json');
            echo $this->server->getServiceMap();
        } 
    
        // Call the API
        else {
            // Handle the request
            $this->server->handle();
        }
    }
}

This basically returns the RPC service mapping description for GET requests and dispatches POST requests to the class which handles the API calls.

The class which handles the API calls (library/Test/Api.php):

<?php
/*
 * JSON API for requests to /api/
 */
class Test_Api {
    /*
     * @param int $bar
     */
    public function foo($bar) {
        return $bar;
    }

    // Add more functions here
}

Make sure the have the Test namespace registered in your application.ini and your library path points to the correct place.

includePaths.library = APPLICATION_PATH "/../library"
autoloaderNamespaces[] = "Test_"

For the frontend JS you need to download Douglas Crockford’s JSON-js library. Copy this to public/js/libs/json2.js.

In whatever view script you want to use the API add:

$this->inlineScript()->appendFile('/js/libs/json2.js'); 

You can also add this to the layout if you want to be able to access the API on every page.

Once you got this in place you can call the API from your JS:

/*
 * JS API Test 
 */
function JsApi() {
    /*
     * Test call
     */
    this.testApi = function() {
        // Request parameters
        var request = {};
        request.method = 'foo';
        request.params = { 'bar': 'baz' };
        request.jsonrpc = '2.0';
        
        // Perform API call
        $.post(
            '/api/',
            JSON.stringify(request), 
            function(response) {
                
                if (!response.result.length) {
                    // API returned nothing; do something
                    return; 
                }

                // Process the response
                $.each(response.result, function () {
                    // Do something
                });
            }
        );
    }

}

$(document).ready(function() {
    // Perform a test call
    var jsApi = new JsApi();
    jsApi.testApi();
});

This relies on the jQuery library. If you are using other JS libraries you need to adjust this accordingly.

Zend JSON Server