JSON-RPC Version 2 API

Updated . Posted . Visible to the public.

nginx URL rewrite Show archive.org snapshot

stackoverflow Show archive.org snapshot

PHP lib Show archive.org snapshot

M1 Extension Show archive.org snapshot and the blog Show archive.org snapshot , version 2.

API Implementation Doc Show archive.org snapshot

Client Show archive.org snapshot based on ZF1, version 2.

Specification Show archive.org snapshot

Response object

When a rpc call is made, the Server MUST reply with a Response, except for in the case of Notifications. The Response is expressed as a single JSON Object, with the following members:

jsonrpc
A String specifying the version of the JSON-RPC protocol. MUST be exactly "2.0".

result
This member is REQUIRED on success.
This member MUST NOT exist if there was an error invoking the method.
The value of this member is determined by the method invoked on the Server.

error
This member is REQUIRED on error.
This member MUST NOT exist if there was no error triggered during invocation.
The value for this member MUST be an Object as defined in section 5.1.

id
This member is REQUIRED.
It MUST be the same as the value of the id member in the Request Object.
If there was an error in detecting the id in the Request object (e.g. Parse error/Invalid Request), it MUST be Null.

Either the result member or error member MUST be included, but both members MUST NOT be included.

Example:

  object(stdClass)#121 (3) {
    ["result"] => string(32) "bb6f3052b503303a4473990f0e2c2184"
    ["id"] => string(13) "607ff6cd1de84"
    ["jsonrpc"] => string(3) "2.0"
  }

v2 Request

Zend_Json_Server_Request_Http Object
(
    [_rawJson:protected] => {"jsonrpc":"2.0","method":"customerGroupList","id":"60efafaaed751","params":["15c64c1d73bed7682227d1f1159afc00"]}
    [_id:protected] => 60efafaaed751
    [_isMethodError:protected] => 
    [_method:protected] => customerGroupList
    [_methodRegex:protected] => /^[a-z][a-z0-9_.]*$/i
    [_params:protected] => Array
        (
            [0] => 15c64c1d73bed7682227d1f1159afc00
        )

    [_version:protected] => 2.0
)

rawJson

{
  "jsonrpc": "2.0",
  "method": "customerGroupList",
  "id": "60efafaaed751",
  "params": [
    "15c64c1d73bed7682227d1f1159afc00"
  ]
}

Response:

 object(stdClass)#672 (3) {
  ["error"] => object(stdClass)#674 (3) {
    ["code"] => int(-32601)
    ["message"] => string(16) "Method not found"
    ["data"] => NULL
  }
  ["id"] => string(13) "60efafaaed751"
  ["jsonrpc"] => string(3) "2.0"
}

This is because:

// lib\Zend\Json\Server.php
    protected function _handle()
    {
        // ...
        $method = $request->getMethod();
        if (!$this->_table->hasMethod($method)) {
            return $this->fault('Method not found', -32601);
        }

$this->_table contains the public methods defined in app\code\core\Mage\Api\Model\Server\Handler\Abstract.php: startSession, endSession, login, call, etc.

How to fix v2

app\code\core\Mage\Api\Model\Server\Adapter\Jsonrpc.php

  1. Change the request object to make it looks like v1
  2. Add method to $this->_table

Method 1

<?php

/**
 * Webservice JSON-RPC adapter
 */
class Mage_Api_Model_Server_Adapter_Jsonrpc extends Mage_Api_Model_Server_Adapter_Xmlrpc
    implements Mage_Api_Model_Server_Adapter_Interface
{

    /** @var Zend_Json_Server */
    protected $_jsonRpc = null;

    /**
     * Run webservice
     *
     * @return $this
     */
    public function run()
    {
        $this->_jsonRpc = new Zend_Json_Server();
        $this->_jsonRpc->setClass($this->getHandler());
        $request = $this->_jsonRpc->getRequest();
        $response = $this->getController()->getResponse()->clearHeaders()
            ->setHeader('Content-Type', 'application/json; charset=utf-8');
        /**
         * Check soap_v2 style request. v1 style has method "call".
         * But we need to check for other methods such as "login", "startSession", etc.
         * @see Mage_Api_Model_Server_Handler_Abstract for all public functions
         */
        $method = $request->getMethod();
        $methods = array_keys($this->_jsonRpc->getServiceMap()->getServices());
        if (!in_array($method, $methods)) {
            // Convert request to v1 style.
            $request->setMethod('call');
            $params = $request->getParams();
            $sessionId = $params[0];
            unset($params[0]);
            $params = count($params)
                ? [$sessionId, $method, $params]
                : [$sessionId, $method];
            $request->setParams($params);
        }
        $response->setBody($this->_jsonRpc->handle());
        return $this;
    }

    /**
     * @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;
    }

    /**
     * Dispatch webservice fault
     *
     * @param int $code
     * @param string $message
     */
    public function fault($code, $message)
    {
        $code < 0 ?: $code = -$code - 32000;
        throw new Zend_Json_Exception($message, $code);
    }
}
kiatng
Last edit
kiatng
Tags
Posted by kiatng to OpenMage (2021-04-08 00:57)