Skip to content

Latest commit

 

History

History
171 lines (128 loc) · 5.47 KB

README.md

File metadata and controls

171 lines (128 loc) · 5.47 KB

Latest Stable Version Total Downloads Latest Unstable Version License

Build Status Scrutinizer Code Quality Code Coverage SensioLabsInsight

HTTP RPC Server bundle

This bundle provides default controller realisation to handle RPC requests which come to the application via HTTP requests

Implementations

RPC server does not declares any implementation requirements. Some could be

  • JSON-RPC
  • SOAP (extends XML-RPC)

or other custom RPC which operates with method+parameters and utilizes single endpoint for several methods

HTTP Endpoints

Endpoint is a HTTP route which process basic HTTP request, providing initial parsing and processing request data

To enable HTTP endpoint you should enable custom endpoint router loader via the following router configuration:

# app/config/routing.yml
rpc:
  resource: .
  type: endpoint

Resource value is not important, it is ignored when loading routes as the endpoints are configured vua config

Configuration

Basic endpoint configuration looks like

rpc:
  router:
    endpoints:
      my-public-endpoint:
        path: /
        defaults:
          _controller: JsonRpcBundle:JsonRpc:jsonRpc
          _format: json
        context: Default
        resources:
        - "@MyBundle/Resources/config/service_rpc.yml"

This creates endpoint on URL / with generic symfony controller. Also it pre-populates the methods from the service_rpc.yml config file

my-public-endpoint will become a route name, so make sure it does not overlap with other routes until you want it do to this.

Method routing

Each RPC request has method and parameters. You can configure the application to handle different methods within different endpoints with different actions

Generic configuration looks like

my_bundle:
  resource: "@MyBundle/Rpc/"
  prefix: my_bundle/
  type: annotation

Different resource types are supported. Built-in are

Annotation

@Method("my-bundle/my-method", context={"private"}, defaultContext=false) 

Yaml

Different endpoint implementation may utilize different controller name parsers, so MyBundle:Test:entity notation is endpoint-dependent. I.e JSON-RPC may search TestController controller in MyBundle\JsonRpc\TestController

my-bundle/my-method:
  controller: "MyBundle:Test:entity"
  default_context: true
  context: private

Resource

You can pass directory, class, file, yaml config as method source with prefix and context inheritance

The following chaing will result in prefix/annotation/sub method handled by AnnotationController::subAction with private+default context

private:
  resource: jsonrpc_private_nested.yml
  context: private
annotation:
  resource: "@JsonRpcTestBundle/JsonRpc"
  prefix: prefix/
/**
 * Class AnnotationController
 *
 * @package Bankiru\Api\JsonRpc\Test\JsonRpc
 * @Method("annotation/")
 */
class AnnotationController extends Controller
{
    /**
     * @return array
     * @Method("sub")
     */
    public function subAction()
    {
        return [];
    }
}

Events

This bundle repeats the generic symfony request processing flow. You can hook your extension into given system events

  • rpc.request is triggered on handling RPC call
    • Routing happens here
  • rpc.controller is triggered to filter controller (i.e. allows security filtering)
  • rpc.response is triggered whenever response is acquired by the endpoint processor
  • rpc.view is triggered if response, returned from controller is not instance of RpcResponseInterface
  • rpc.exception is triggered when exception is raised during RPC call processing
  • rpc.finish_request is used to finalize RPC response before it is returned to HTTP controller

RPC Controller implementation

The goal of implementing controller is to extend abstract RpcController passing RequestInterface and endpoint name into getResponse method.

RequestInterface is an extension of RpcRequestInterface with extra attributes allowing request metadata carrying alongside the request.

The generic solution is to convert incoming symfony Request instance into your own implementation of RequestInterface (i.e extract method and args from XML-RPC or JSON-RPC requests) and send serialized response back, transforming RpcResponseInterface back to your response object.

You can also automatically convert RpcResponseInterface into your serialized response via generic symfony view event processing