yoanm/jsonrpc-server-sdk

将 JSON-RPC 请求字符串转换为 JSON-RPC 响应字符串的服务器 SDK

v3.3.2 2023-05-06 06:13 UTC

README

License Code size Dependabot Status

Scrutinizer Build Status Scrutinizer Code Quality Codacy Badge

CI codecov

Latest Stable Version Packagist PHP version

简单的服务器 SDK,用于将 JSON-RPC 请求字符串转换为 JSON-RPC 响应字符串。

有关自动依赖注入,请参阅 yoanm/symfony-jsonrpc-http-server

有关参数验证,请参阅 yoanm/jsonrpc-params-symfony-validator-sdk

有关文档生成,请参阅 yoanm/jsonrpc-server-doc-sdk

如何使用

SDK 仅需要两样东西

SDK 可选提供

  • 事件调度
  • 参数验证

简单示例

JSON-RPC 方法

use Yoanm\JsonRpcServer\Domain\JsonRpcMethodInterface;

class DummyMethod implements JsonRpcMethodInterface
{
    /**
     * {@inheritdoc}
     */
    public function apply(array $paramList = null)
    {
        // Handle the request
        ...
        // Then return a result
        return [
            'status' => 'done',
        ];
        // Or
        return null;
        // Or
        return 12345;
    }
}

数组方法解析器(简单示例)

您可以使用 behat 测试中使用的 或此 Psr11 方法解析器 作为示例。

use Yoanm\JsonRpcServer\Domain\JsonRpcMethodInterface;
use Yoanm\JsonRpcServer\Domain\JsonRpcMethodResolverInterface;

class ArrayMethodResolver implements JsonRpcMethodResolverInterface
{
    /** @var JsonRpcMethodInterface[] */
    private $methodList = [];

    /**
     * {@inheritdoc}
     */
    public function resolve(string $methodName) : ?JsonRpcMethodInterface
    {
        return array_key_exists($methodName, $this->methodList)
            ? $this->methodList[$methodName]
            : null
        ;
    }

    /**
     * @param JsonRpcMethodInterface $method
     * @param string                 $methodName
     */
    public function addMethod(JsonRpcMethodInterface $method, string $methodName)
    {
        $this->methodList[$methodName] = $method;
    }
}

然后将您的 方法添加到解析器中并创建端点

use Yoanm\JsonRpcServer\App\Creator\ResponseCreator;
use Yoanm\JsonRpcServer\App\Handler\ExceptionHandler;
use Yoanm\JsonRpcServer\App\Handler\JsonRpcRequestHandler;
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcCallDenormalizer;
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcCallResponseNormalizer;
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcCallSerializer;
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcRequestDenormalizer;
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcResponseErrorNormalizer;
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcResponseNormalizer;
use Yoanm\JsonRpcServer\Infra\Endpoint\JsonRpcEndpoint;

$resolver = new ArrayMethodResolver();
$resolver->addMethod('dummy-method', new DummyMethod());

$jsonRpcSerializer = new JsonRpcCallSerializer(
    new JsonRpcCallDenormalizer(
        new JsonRpcRequestDenormalizer()
    ),
    new JsonRpcCallResponseNormalizer(
        new JsonRpcResponseNormalizer() 
        // Or `new JsonRpcResponseNormalizer(new JsonRpcResponseErrorNormalizer())` for debug purpose
        // To also dump arguments, be sure 'zend.exception_ignore_args' ini option is not at true/1
    )
);
$responseCreator = new ResponseCreator();
$requestHandler = new JsonRpcRequestHandler($resolver, $responseCreator);
$exceptionHandler = new ExceptionHandler($responseCreator);

$endpoint = new JsonRpcEndpoint($jsonRpcSerializer, $requestHandler, $exceptionHandler);

端点准备就绪后,您可以发送请求字符串

$requestString = <<<JSONRPC
{
    "jsonrpc": "2.0",
    "id": 1
    "method": "dummy-method"
}
JSONRPC;

$responseString = $endpoint->index($requestString);

$responseString 将根据方法的返回值成为以下字符串

  • {"jsonrpc":"2.0","id":1,"result":{"status":"done"}}
  • {"jsonrpc":"2.0","id":1,"result":null}
  • {"jsonrpc":"2.0","id":1,"result":12345}

事件调度示例

简单事件调度器

您可以使用 behat 测试中使用的 作为示例。

use Yoanm\JsonRpcServer\Domain\Event\JsonRpcServerEvent;
use Yoanm\JsonRpcServer\Domain\JsonRpcServerDispatcherInterface;

/**
 * Class SimpleDispatcher
 */
class SimpleDispatcher implements JsonRpcServerDispatcherInterface
{
    /** @var callable[] */
    private $listenerList = [];

    /**
     * {@inheritdoc}
     */
    public function dispatchJsonRpcEvent(string $eventName, JsonRpcServerEvent $event = null) : void
    {
        if (!array_key_exists($eventName, $this->listenerList)) {
            return;
        }

        foreach ($this->listenerList[$eventName] as $listener) {
            $listener($event, $eventName);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function addJsonRpcListener(string $eventName, $listener) : void
    {
        $this->listenerList[$eventName][] = $listener;
    }
}

然后将您的监听器绑定到您的调度器上

use Yoanm\JsonRpcServer\Domain\Event\Acknowledge\OnRequestReceivedEvent;
use Yoanm\JsonRpcServer\Domain\Event\Acknowledge\OnResponseSendingEvent;
use Yoanm\JsonRpcServer\Domain\Event\Action\OnMethodSuccessEvent;

$dispatcher = new SimpleDispatcher();

$listener = function ($event, $eventName) {
    echo sprintf(
        'Received %s with event class "%s"',
        $eventName,
        get_class($event)
    );
};

$dispatcher->addJsonRpcListener(OnRequestReceivedEvent::EVENT_NAME, $listener);
$dispatcher->addJsonRpcListener(OnResponseSendingEvent::EVENT_NAME, $listener);
$dispatcher->addJsonRpcListener(OnMethodSuccessEvent::EVENT_NAME, $listener);

并按以下方式绑定调度器

$endpoint->setJsonRpcServerDispatcher($dispatcher);
$requestHandler->setJsonRpcServerDispatcher($dispatcher);
$exceptionHandler->setJsonRpcServerDispatcher($dispatcher);

事件已分发

基本请求生命周期
  • json_rpc_server_skd.on_request_received / Acknowledge\OnRequestReceivedEvent

    当一个请求已传递到端点并成功反序列化时,将触发此事件。

    注意:当请求字符串不是有效的 JSON-RPC 请求时,不会触发此事件。

    它包括

    • 解析错误异常(格式不正确的 JSON 字符串)

    • 对于简单请求,在无效请求(不是对象 / 缺少必需属性 / ...)的情况下。

      ⚠️ 对于包含无效子请求的批请求,此事件仍将被触发

  • 或者是

    • json_rpc_server_skd.on_method_success / Action\OnMethodSuccessEvent

      只有在 JSON-RPC 方法已成功执行的情况下才会触发。

    • json_rpc_server_skd.on_method_failure / Action\OnMethodFailureEvent

      只有在 JSON-RPC 方法在执行过程中抛出异常的情况下才会触发。

  • json_rpc_server_skd.on_response_sending / Acknowledge\OnResponseSendingEvent

    当端点成功序列化响应时触发,并将被返回。

其他事件
批量请求
异常

json_rpc_server_skd.on_exception / Action\OnExceptionEvent

在SDK执行期间发生异常时触发。

行为与确认事件
确认

它们只有确认的目的。

它们被分组在Yoanm\JsonRpcServer\Domain\Event\Acknowledge命名空间下。

行为

它们允许您覆盖内容。

它们被分组在Yoanm\JsonRpcServer\Domain\Event\Action命名空间下。

这里,列表

参数验证示例

您可以使用此 JSON-RPC params symfony validator 作为示例

为了验证给定方法的参数,请执行以下操作

use Yoanm\JsonRpcServer\Domain\JsonRpcMethodInterface;
use Yoanm\JsonRpcServer\Domain\JsonRpcMethodParamsValidatorInterface;
use Yoanm\JsonRpcServer\Domain\Model\JsonRpcRequest;

$validator = new class implements JsonRpcMethodParamsValidatorInterface
{
    public function validate(JsonRpcRequest $jsonRpcRequest, JsonRpcMethodInterface $method) : array
    {
        if (!(/** Skip unexpected method */)) {
            return [];
        }

        // Create your violations based on what you want
        $paramList = $jsonRpcRequest->getParamList();
        $violation = "???";

        return [$violation];
    }
};

$requestHandler->setMethodParamsValidator($validator);

贡献

查看 贡献说明