Skip to content

Server usage

johnstevenson edited this page Sep 26, 2012 · 35 revisions

Contents

The Basics

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:

Methods Class

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

Errors and Exceptions

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.

Custom error-logging

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
  }

}

Advanced

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.

Clone this wiki locally