/** * An overview of how to use the JsonRpcRequest class. * @test */ public function synopsis() { /* Handles JSON-RPC 1.0 requests. */ $request = new JsonRpcRequest('MyService', (object) array('method' => 'remoteProcedure', 'params' => array(1, 2, 3), 'id' => 'uniqueidentifier')); $this->assertEquals('POST', $request->getVerb()); $this->assertEquals('remoteProcedure', $request->getMethod()); $this->assertEquals('1.0', $request->getVersion()); $this->assertEquals(array(1, 2, 3), $request->getParameters()); $this->assertEquals('uniqueidentifier', $request->getIdentifier()); $this->assertNull($request->getPost('anything')); // Post should be ignored. /* Handles JSON-RPC 2.0 requests. */ $request = new JsonRpcRequest('MyService', (object) array('jsonrpc' => '2.0', 'method' => 'remoteProcedure', 'id' => 'uniqueidentifier')); $this->assertEquals('2.0', $request->getVersion()); $this->assertEquals(array(), $request->getParameters()); /* Catches invalid request format. */ $request = new JsonRpcRequest('MyService', (object) array('jsonrpc' => '2.0', 'method' => null)); $this->assertFalse($request->isValid()); }
/** * Construct a Response from JSON-RPC style result, error, and JSON-RPC request. * * @param mixed $result The result of the remote procedure call. * @param Exception $error The error, as an exception. (Requires code and message.) * @param JsonRpcRequest $request The request that led to the generation of this response. */ public function __construct($result, Exception $error = null, JsonRpcRequest $request = null) { $response = new stdClass(); /* JSON-RPC spec: either error or result, never both. */ if ($error) { $response->error = (object) array('code' => $error->getCode(), 'message' => $error->getMessage()); } else { $response->result = $result; } if ($request) { /* 1.0: omit version, 2.0 and newer, echo back version. */ if ($request->getVersion() != "1.0") { $response->jsonrpc = $request->getVersion(); } /* For notifications (null id), return nothing. Otherwise, pass back the id. */ if ($request->getIdentifier() === null) { $response = ""; } else { $response->id = $request->getIdentifier(); } } parent::__construct($response); }
/** * Invokes a method on a service class, based on the raw JSON-RPC request. * * @param mixed $service The service being invoked. * @param Vectorface\SnappyRouter\Request\JsonRpcRequest $request The request * to invoke. * @return JsonRpcResponse A response based on the result of the procedure call. */ private function invokeMethod($service, JsonRpcRequest $request) { if (false === $request->isValid()) { /* Note: Method isn't known, so invocation hooks aren't called. */ return new JsonRpcResponse(null, new Exception('The JSON sent is not a valid Request object', self::ERR_INVALID_REQUEST)); } $action = $request->getAction(); $this->invokePluginsHook('afterServiceSelected', array($this, $request, $service, $action)); $this->invokePluginsHook('beforeMethodInvoked', array($this, $request, $service, $action)); try { $response = new JsonRpcResponse(call_user_func_array(array($service, $action), $request->getParameters()), null, $request); } catch (Exception $e) { $error = new Exception($e->getMessage(), self::ERR_INTERNAL_ERROR); $response = new JsonRpcResponse(null, $error, $request); } $this->invokePluginsHook('afterMethodInvoked', array($this, $request, $service, $action, $response)); return $response; }