A JSON-RPC Adapter For The Magento API

Going through my old answers on Magento StackExchange, I found this question about using the Magento API via JavaScript and noticed that the link to GitHub that contained an important part of the solution, namely implementing a JSON-RPC adapter for the Magento-API is dead now.

So I decided to publish my complete module myself (the original link was a core hack, I rewrote it as a clean module):

GitHub: SGH_JsonRpc

The whole module is less than 100 lines of code. In config.xml our controller is added to the api route:

    <frontend>
        <routers>
            <api>
                <args>
                    <modules>
                        <sgh_jsonrpc before="Mage_Api">SGH_JsonRpc_Api</sgh_jsonrpc>
                    </modules>
                </args>
            </api>
        </routers>
    </frontend>

The new API adapter is defined in api.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <api>
        <adapters>
            <jsonrpc>
                <model>sgh_jsonrpc/api_server_adapter_jsonrpc</model>
                <handler>default</handler>
                <active>1</active>
            </jsonrpc>
        </adapters>
    </api>
</config>

The controller is very thin and works the same way as Mage_Api_XmlrpcController. Additionally it implements the method methodsAction, so that a request to /api/jsonrpc/methods returns a service definition.

class SGH_JsonRpc_Api_JsonrpcController extends Mage_Api_Controller_Action
{
    public function indexAction()
    {
        $this->_getServer()->init($this, 'jsonrpc')->run();
    }
    public function methodsAction()
    {
        $this->_getServer()->init($this, 'jsonrpc')->getAdapter()->serviceMap();
    }
}

And finally, the API adapter. Basically it’s a copy of Mage_Api_Model_Server_Adapter_Xmlrpc where the Zend_XmlRpc classes were replaced with their Zend_Json equivalent:

class SGH_JsonRpc_Model_Api_Server_Adapter_Jsonrpc extends Varien_Object
        implements Mage_Api_Model_Server_Adapter_Interface {

    protected $_jsonRpc = null;

    public function setHandler($handler) {
        $this->setData('handler', $handler);
        return $this;
    }

    public function getHandler() {
        return $this->getData('handler');
    }

    public function setController(Mage_Api_Controller_Action $controller) {
        $this->setData('controller', $controller);
        return $this;
    }

    public function getController() {
        $controller = $this->getData('controller');

        if (null === $controller) {
            $controller = new Varien_Object(
                array(
                    'request'  => Mage::app()->getRequest(),
                    'response' => Mage::app()->getResponse()
                )
            );
            $this->setData('controller', $controller);
        }
        return $controller;
    }

    public function run() {
        $this->_jsonRpc = new Zend_Json_Server();
        $this->_jsonRpc->setClass($this->getHandler());
        $this->getController()->getResponse()->clearHeaders()
             ->setHeader('Content-Type', 'application/json; charset=utf-8')
             ->setBody($this->_jsonRpc->handle());
        return $this;
    }

    public function serviceMap() {
        $this->_jsonRpc = new Zend_Json_Server();
        $this->_jsonRpc->setClass($this->getHandler());
        $this->getController()->getResponse()->clearHeaders()
             ->setHeader('Content-type', 'application/json; charset=utf-8')
             ->setBody($this->_jsonRpc->getServiceMap());
        return $this;
    }

    public function fault($code, $message) {
        throw new Zend_Json_Exception($message, $code);
    }
}

That’s it! Now the API can be accessed at /api/jsonrpc with the same methods as the XML-RPC API.

6 Replies to “A JSON-RPC Adapter For The Magento API”

  1. I tried it and accessed it from my android application and I get this error. Can you please look into it.
    a:5:{i:0;s:29:”Decoding failed: Syntax error”;i:1;s:1741:”#0 D:\wamp_2.5\www\magento_default\lib\Zend\Json\Server\Request.php(251): Zend_Json::decode(‘loadJson(‘<?xml version='…')

      1. Thank you for reply,
        How can I make json request, if you can give some sample would be great help.

  2. Hi,
    How to make request in php.

    login('Guest', '18181xxxxxxxx76767667xxx');
    $result = $proxy->catalogProductList($sessionId);
    var_dump($result);
    } catch (Exception $e) {
    echo nl2br($e->getMessage()).''."\n";
    }
    ?>

    It is returning session but when I tried to print result. It is displaying “Request error: Array” . Can you please help on this. Thanks

Comments are closed.