Flexible JSON-RPC2 server/client implementation for PHP7.
- JSON-RPC 2.0 full conformance (batch requests, notification, positional and named arguments, etc).
- Quick-start with default routing based on php namespaces.
- Flexible custom routing for your requirements.
- The mechanism of intercepting requests and responses through handlers.
- Automatic casting types in requests and responses.
- Fully unit tested.
Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle:
$ composer require vaderangry/php-json-rpc
This command requires you to have Composer installed globally, as explained in the installation chapter of the Composer documentation.
The example of quick-start:
<?php
use PhpJsonRpc\Server;
// Class for which provide JSON-RPC2 API:
class Math
{
public function pow(float $base, int $exp): float
{
return pow($base, $exp);
}
}
$server = new Server();
$response = $server
->addHandler(new Math())
->execute();
echo $response;
Method Math::pow
by default will mapped to method Math.pow
in JSON-RPC2 terms. Request example:
{
"jsonrpc": "2.0",
"method": "Math.pow",
"params": {"base": 2, "exp": 3},
"id": 1
}
The example of custom method mapping:
<?php
use PhpJsonRpc\Server;
use PhpJsonRpc\Server\MapperInterface;
// Define custom mapper
class Mapper implements MapperInterface
{
public function getClassAndMethod(string $requestedMethod): array
{
// Keys of array presents requested method
$map = [
'pow' => [Math::class, 'pow'],
];
if (array_key_exists($requestedMethod, $map)) {
return $map[$requestedMethod];
}
return ['', ''];
}
}
$server = new Server();
// Register new mapper
$server->setMapper(new Mapper());
// Register handler and run server
$response = $server->addHandler(new Math())->execute();
echo $response;
Now Math::pow
will be mapped to pow
. Request example:
{
"jsonrpc": "2.0",
"method": "pow",
"params": {"base": 2, "exp": 3},
"id": 1
}
Single request:
<?php
use PhpJsonRpc\Client;
$client = new Client('http://localhost');
$result = $client->call('Math.pow', [2, 3]); // $result = 8
$result = $client->call('Math.methodNotFound', []); // $result = null
Single request with exception server error mode:
<?php
use PhpJsonRpc\Client;
$client = new Client('http://localhost', Client::ERRMODE_EXCEPTION);
$result = $client->call('Math.methodNotFound', []); // throw MethodNotFoundException
Batch request:
<?php
use PhpJsonRpc\Client;
$client = new Client('http://localhost');
$result = $client->batch()
->call('Util.Math.pow', [2, 1])
->call('Util.Math.pow', [2, 2])
->call('Util.Math.pow', [2, 3])
->call('Util.methodNotFound', [])
->batchExecute();
// $result = [2, 4, 8, null]
All unit of result stored at the same position of call. Server error present null
object.
Batch request with exception server error mode:
<?php
use PhpJsonRpc\Client;
$client = new Client('http://localhost', Client::ERRMODE_EXCEPTION);
$result = $client->batch()
->call('Util.Math.pow', [2, 1])
->call('Util.methodNotFound', [])
->batchExecute();
// $result = [2, MethodNotFoundException]
With exception mode server error present JsonRpcException
object.
Exception will not throw for saving other units of result.
The example with personal custom headers in request:
<?php
use PhpJsonRpc\Client;
use PhpJsonRpc\Common\Interceptor\Container;
use PhpJsonRpc\Common\Interceptor\Interceptor;
$client = new Client('http://localhost');
$client->getTransport()->onPreRequest()
->add(Interceptor::createWith(function (Container $container) {
// Get transport from container
$transport = $container->first();
// Add required headers
$transport->addHeaders([
"Origin: " . $_SERVER['HTTP_HOST'],
]);
// Now we MUST return container for next chain
return new Container($transport, $container->last());
}));
$result = $client->call('Math.pow', [2, 3]); // $result = 8
$ ./vendor/bin/phpunit -c ./