-
Notifications
You must be signed in to change notification settings - Fork 29
Server usage
The server provides a robust mechanism for handling all JSON-RPC requests, including notification and batch requests. It also provides custom error-logging and advanced functionality.
Setting it up, however, is simple. All you need is a class containing the methods that you expose to the client, which you pass to the constructor of JsonRpc\Server
. For an instantiated class:
<?php
$methods = new MethodsClass();
$server = new JsonRpc\Server($methods);
For a static class:
<?php
$server = new JsonRpc\Server('\\\\Namespace\\\\MethodsStatic');
Then you call the $server->receive
method, which will do all the work for you:
<?php
$server->receive();
And that is it. The library will handle all requests, invoke your methods and return the response. It also handles any errors it may encounter. The requirements of the methods class are described below:
It must be a class, because the server looks-up the method to check and order its parameters. If you used an ordinary function
or closure
this would not be possible.
It should contain a public property error
which is used by your methods to signify an error and is returned by the server as an appropriate error response. Take a look at the example method class below.
<?php
class MyMethodsClass
{
public $error = null;
public function divide($dividend, $divisor, $int = false)
{
if (!$divisor)
{
$this->error = 'Cannot divide by zero';
}
else
{
$quotient = $dividend / $divisor;
return $int ? (int) $quotient : $quotient;
}
}
}
If the divide
method is passed 0
as its divisor, it sets the error
property to a string message. The server checks for this and returns an appropriate JSON-RPC response:
{"jsonrpc": "2.0", "error": {"code": -32000, "message": "Server error", "data": "Cannot divide by zero"}, "id": 1}
The format is explained in the official specification. Note, however, that the error code used is reserved for "implementation-defined server-errors" and that the error
property is used as the data
member of the error structure. You can set your own error codes and messages by using an array or object. For example the above error could be set as:
<?php
$this->error = array(
'code' => -32000,
'message' => 'Server error',
'data' => 'Cannot divide by zero'
);
The server uses the following rules for interpreting the error
property of the method class:
- if it is an integer it is set as the code:
{"code": <error>, "message": "Server error"}
- if it is a scalar it is set as the data:
{"code": -32000, "message": "Server error","data":<error>}
- if it is an array or object it uses any values it finds, defaulting to:
{"code": -32000, "message": "Server error"}
* Note that an Exception
will be thrown if you set the error code outside of the accepted range (-32000 to -32099).
Tip: The server will always set the
error
property to null before calling a method
The server switches display_errors
off so that no error output is sent to the client and it also handles all errors and exceptions that might occur. For example:
- if the method does not exist (or is not callable)
- if the method call does not have the correct number of required parameters
- if an
Exception
is thrown in your methods class
These conditions are returned with the appropriate error response and in the case of exceptions are logged using PHP's error_log
function. Of course this requires that log_errors
is enabled.
If you want to use more advanced logging, like monolog for example, then you can pass an instance of your logger to the $server->setLogger
function:
<?php
$server = new JsonRpc\Server($methods);
$log = new Logger('name');
$server->setLogger($log);
Internally, the server calls the addRecord
function of the logger instance with a level of CRITICAL
(see RFC 5424) and a message obtained from Exception->getMessage()
. If you provide you own logging class it should look something like this:
<?php
class MyLoggingClass
{
public function addRecord($level, $message, array $context = array())
{
// do logging stuff
}
}
The built-in transport mechanism reads php://input
to obtain the data sent by the client. If this is restrictive you can override it by passing the input data to the $server->receive
function.
<?php
// get the input sent from the client and do something with it
$server = new JsonRpc\Server($methods);
$server->receive($input);
Note that this does not give you any control over the data being returned to the client. If you need access to this then you must supply your own transport mechanism. See the Advanced functionality topic for more details.