项目作者: yoanm

项目描述 :
Server SDK to convert a json-rpc request string into json-rpc response string
高级语言: PHP
项目地址: git://github.com/yoanm/php-jsonrpc-server-sdk.git
创建时间: 2018-03-31T13:13:31Z
项目社区:https://github.com/yoanm/php-jsonrpc-server-sdk

开源协议:MIT License

下载


PHP JSON-RPC server sdk

License
Code size
Dependabot Status

Scrutinizer Build Status
Scrutinizer Code Quality
Codacy Badge

CI
codecov

Latest Stable Version
Packagist PHP version

Simple server SDK to convert a json-rpc request string into json-rpc response string.

See yoanm/symfony-jsonrpc-http-server for automatic dependency injection.

See yoanm/jsonrpc-params-symfony-validator-sdk for params validation.

See yoanm/jsonrpc-server-doc-sdk for documentation generation.

How to use

Sdk requires only two things :

Sdk optionally provide :

  • Events dispatch
  • Params validation

Simple Example

JSON-RPC Method

  1. use Yoanm\JsonRpcServer\Domain\JsonRpcMethodInterface;
  2. class DummyMethod implements JsonRpcMethodInterface
  3. {
  4. /**
  5. * {@inheritdoc}
  6. */
  7. public function apply(array $paramList = null)
  8. {
  9. // Handle the request
  10. ...
  11. // Then return a result
  12. return [
  13. 'status' => 'done',
  14. ];
  15. // Or
  16. return null;
  17. // Or
  18. return 12345;
  19. }
  20. }

Array method resolver (simple example)

You can use the one used for behat tests or this Psr11 method resolver as example

  1. use Yoanm\JsonRpcServer\Domain\JsonRpcMethodInterface;
  2. use Yoanm\JsonRpcServer\Domain\JsonRpcMethodResolverInterface;
  3. class ArrayMethodResolver implements JsonRpcMethodResolverInterface
  4. {
  5. /** @var JsonRpcMethodInterface[] */
  6. private $methodList = [];
  7. /**
  8. * {@inheritdoc}
  9. */
  10. public function resolve(string $methodName) : ?JsonRpcMethodInterface
  11. {
  12. return array_key_exists($methodName, $this->methodList)
  13. ? $this->methodList[$methodName]
  14. : null
  15. ;
  16. }
  17. /**
  18. * @param JsonRpcMethodInterface $method
  19. * @param string $methodName
  20. */
  21. public function addMethod(JsonRpcMethodInterface $method, string $methodName)
  22. {
  23. $this->methodList[$methodName] = $method;
  24. }
  25. }

Then add your method to the resolver and create the endpoint :

  1. use Yoanm\JsonRpcServer\App\Creator\ResponseCreator;
  2. use Yoanm\JsonRpcServer\App\Handler\ExceptionHandler;
  3. use Yoanm\JsonRpcServer\App\Handler\JsonRpcRequestHandler;
  4. use Yoanm\JsonRpcServer\App\Serialization\JsonRpcCallDenormalizer;
  5. use Yoanm\JsonRpcServer\App\Serialization\JsonRpcCallResponseNormalizer;
  6. use Yoanm\JsonRpcServer\App\Serialization\JsonRpcCallSerializer;
  7. use Yoanm\JsonRpcServer\App\Serialization\JsonRpcRequestDenormalizer;
  8. use Yoanm\JsonRpcServer\App\Serialization\JsonRpcResponseErrorNormalizer;
  9. use Yoanm\JsonRpcServer\App\Serialization\JsonRpcResponseNormalizer;
  10. use Yoanm\JsonRpcServer\Infra\Endpoint\JsonRpcEndpoint;
  11. $resolver = new ArrayMethodResolver();
  12. $resolver->addMethod('dummy-method', new DummyMethod());
  13. $jsonRpcSerializer = new JsonRpcCallSerializer(
  14. new JsonRpcCallDenormalizer(
  15. new JsonRpcRequestDenormalizer()
  16. ),
  17. new JsonRpcCallResponseNormalizer(
  18. new JsonRpcResponseNormalizer()
  19. // Or `new JsonRpcResponseNormalizer(new JsonRpcResponseErrorNormalizer())` for debug purpose
  20. // To also dump arguments, be sure 'zend.exception_ignore_args' ini option is not at true/1
  21. )
  22. );
  23. $responseCreator = new ResponseCreator();
  24. $requestHandler = new JsonRpcRequestHandler($resolver, $responseCreator);
  25. $exceptionHandler = new ExceptionHandler($responseCreator);
  26. $endpoint = new JsonRpcEndpoint($jsonRpcSerializer, $requestHandler, $exceptionHandler);

Once endpoint is ready, you can send it request string :

  1. $requestString = <<<JSONRPC
  2. {
  3. "jsonrpc": "2.0",
  4. "id": 1
  5. "method": "dummy-method"
  6. }
  7. JSONRPC;
  8. $responseString = $endpoint->index($requestString);

$responseString will be the following string depending of method returned value :

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

Events dispatch example

Simple event dispatcher

You can use the one used for behat tests as example

  1. use Yoanm\JsonRpcServer\Domain\Event\JsonRpcServerEvent;
  2. use Yoanm\JsonRpcServer\Domain\JsonRpcServerDispatcherInterface;
  3. /**
  4. * Class SimpleDispatcher
  5. */
  6. class SimpleDispatcher implements JsonRpcServerDispatcherInterface
  7. {
  8. /** @var callable[] */
  9. private $listenerList = [];
  10. /**
  11. * {@inheritdoc}
  12. */
  13. public function dispatchJsonRpcEvent(string $eventName, JsonRpcServerEvent $event = null) : void
  14. {
  15. if (!array_key_exists($eventName, $this->listenerList)) {
  16. return;
  17. }
  18. foreach ($this->listenerList[$eventName] as $listener) {
  19. $listener($event, $eventName);
  20. }
  21. }
  22. /**
  23. * {@inheritdoc}
  24. */
  25. public function addJsonRpcListener(string $eventName, $listener) : void
  26. {
  27. $this->listenerList[$eventName][] = $listener;
  28. }
  29. }

Then bind your listeners to your dispatcher:

  1. use Yoanm\JsonRpcServer\Domain\Event\Acknowledge\OnRequestReceivedEvent;
  2. use Yoanm\JsonRpcServer\Domain\Event\Acknowledge\OnResponseSendingEvent;
  3. use Yoanm\JsonRpcServer\Domain\Event\Action\OnMethodSuccessEvent;
  4. $dispatcher = new SimpleDispatcher();
  5. $listener = function ($event, $eventName) {
  6. echo sprintf(
  7. 'Received %s with event class "%s"',
  8. $eventName,
  9. get_class($event)
  10. );
  11. };
  12. $dispatcher->addJsonRpcListener(OnRequestReceivedEvent::EVENT_NAME, $listener);
  13. $dispatcher->addJsonRpcListener(OnResponseSendingEvent::EVENT_NAME, $listener);
  14. $dispatcher->addJsonRpcListener(OnMethodSuccessEvent::EVENT_NAME, $listener);

And bind dispatcher like following :

  1. $endpoint->setJsonRpcServerDispatcher($dispatcher);
  2. $requestHandler->setJsonRpcServerDispatcher($dispatcher);
  3. $exceptionHandler->setJsonRpcServerDispatcher($dispatcher);

Events dispatched

Basic request lifecycle
  • json_rpc_server_skd.on_request_received / Acknowledge\OnRequestReceivedEvent

    Dispatched when a request has been passed to the endpoint and successfully deserialized.

    N.B. : Lonely cases where this event is not dispatched are when the request string is not a valid JSON-RPC request.

    It include :

    • Parse error exception (malformed json string)
    • For simple request only, in case of Invalid request (not an object / missing required properties / …).

      :warning: For batch request containing Invalid SubRequest, this event will still be dispatched

  • Either

    • json_rpc_server_skd.on_method_success / Action\OnMethodSuccessEvent

      Dispatched only in case JSON-RPC method has been successfully executed.

    • json_rpc_server_skd.on_method_failure / Action\OnMethodFailureEvent

      Dispatched only in case JSON-RPC method throw an exception during execution.

  • json_rpc_server_skd.on_response_sending / Acknowledge\OnResponseSendingEvent

    Dispatched when a response has been successfully serialized by the endpoint and will be returned.

Additional events
Batch request
Exception

json_rpc_server_skd.on_exception / Action\OnExceptionEvent

Dispatched when an exception occurred during sdk execution

Action vs Acknowledge events
Acknowledge

They have only an acknowledge purpose.

They are grouped under Yoanm\JsonRpcServer\Domain\Event\Acknowledge namespace.

Action

They allow you to override stuffs.

They are grouped under Yoanm\JsonRpcServer\Domain\Event\Action namespace.

Here, the list :

Params validation example

You can use this JSON-RPC params symfony validator as example

To validate params for a given method, do the following :

  1. use Yoanm\JsonRpcServer\Domain\JsonRpcMethodInterface;
  2. use Yoanm\JsonRpcServer\Domain\JsonRpcMethodParamsValidatorInterface;
  3. use Yoanm\JsonRpcServer\Domain\Model\JsonRpcRequest;
  4. $validator = new class implements JsonRpcMethodParamsValidatorInterface
  5. {
  6. public function validate(JsonRpcRequest $jsonRpcRequest, JsonRpcMethodInterface $method) : array
  7. {
  8. if (!(/** Skip unexpected method */)) {
  9. return [];
  10. }
  11. // Create your violations based on what you want
  12. $paramList = $jsonRpcRequest->getParamList();
  13. $violation = "???";
  14. return [$violation];
  15. }
  16. };
  17. $requestHandler->setMethodParamsValidator($validator);

Contributing

See contributing note