ufo-cms/json-rpc-bundle

The bundle for easy using json-rpc api on your project


Keywords
symfony, api, bundle, json-rpc, Ufo
License
MIT

Documentation

ufo-tech/json-rpc-bundle 4

Ukraine

JSON-RPC 2.0 server for Symfony v.6.*

About this package

Package for easy api creation using json-rpc server

License Size package_version fork

Environmental requirements

php_version symfony_version symfony_version

What's new?

Version 4.2

  • Implemented multi-process processing of batch requests, which reduces the response time to the time of the longest request
  • Implemented response subscription mechanism thanks to service parameter $rpc.callback Request:
{
    "id": "someIdForCreateWebhook",
    "method": "SomeEntityProcedure.create",
    "params": {
        "name": "test",
        "$rpc.callback": "https://mycalback.url/endpoint"
    }
}

Response:

{
    "id": "someIdForCreateWebhook",
    "result": {
        "callback": {
            "url": "https://mycalback.url/endpoint",
            "status": true,
            "data": []
        }
    },
    "jsonrpc": "2.0"
}

Version 4.1

  • Full support for batch requests with the possibility of transferring the results of one request to the parameters of the second Request:
[
    {
        "id": "someIdForCreateWebhook",
        "method": "SomeEntityProcedure.create",
        "params":{
            "name": "test"
        }
    },
    {
        "id": "someIdForActivateWebhook",
        "method": "SomeEntityProcedure.changeStatus",
        "params":{
            "id": "@FROM:someIdForCreateWebhook(id)",
            "status": 1
        }
    }
]

Response:

[
    {
        "id": "someIdForCreateWebhook",
        "result": {
            "id": 123
        }
    },
    {
        "id": "someIdForActivateWebhook",
        "result": "SomeEntity 123 have status 1"
    }
]

Getting Started

Automatic package installation in Symfony

Step 0 (RECOMMENDED): Configure Composer

In order for your Symfony Flex to automatically make all the necessary settings when you add a package, you need to make the following changes to your composer.json

// composer.json    

// ...  
  
    "extra" : {
  
        // ...  
  
        "symfony": {
  
            // ...  
  
            "endpoint": [
                "https://api.github.com/repos/ufo-tech/recipes/contents/index.json?ref=main",
                "flex://defaults"
            ]
        }
  
        // ...  
  
    },

// ...  
  

More about Symfony Flex in doc

Step 1: Installation

From the console in the project folder, run this command to download the latest version of this package:

$ composer requires ufo-tech/json-rpc-bundle 4.*

This command is relevant if you have installed Composer globally as described in doc Composer documentation.

Step 2: Register the package

Make sure that the bundle is automatically registered in your project's `config/bundles.php' file:

<?php
// config/bundles.php

return [
    // ...
    Ufo\JsonRpcBundle\UfoJsonRpcBundle::class => ['all' => true],
    // ...
];

Step 3: Adding parameters

Add an empty parameters section: In the config/packages folder, add the ufo_api.yaml file with the following content

# config/packages/ufo_json_rpc.yaml
ufo_json_rpc:
    security:
        # default parameters is enabled

In the future, we will configure the package here

Step 4: Registration of routes

In the config/routes folder, add the ufo_api.yaml file with the following content

# config/routes/ufo_json_rpc.yaml
ufo_json_rpc_bundle:
    resource: ../../vendor/ufo-tech/json-rpc-bundle/config/router.yaml
    prefix: /api
    trailing_slash_on_root: false

By default, the API is available at the url http://example.com/api If you need to change the url, reconfigure the route as follows:

# config/routes/ufo_json_rpc.yaml
ufo_json_rpc_bundle:
    resource: ../../vendor/ufo-tech/json-rpc-bundle/config/router.yaml
    prefix: /my_new_api_path
    trailing_slash_on_root: false

The API will be available at the url http://example.com/my_new_api_path

##Congratulations, your RPC server is ready to go!!!

Examples of use

GET /api:

{
    "transport": "POST",
    "envelope": "JSON-RPC-2.0",
    "contentType": "application/json",
    "SMDVersion": "2.0",
    "description": null,
    "target": "/api",
    "services": {
        "ping": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "ping",
            "parameters": [],
            "returns": "string"
        }
    },
    "methods": {
        "ping": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "name": "ping",
            "parameters": [],
            "returns": "string"
        }
    }

}

The ping method is set right away, you can do a POST request right away to make sure the server is working.

POST /api

Request:

{
     "id":123,
     "method": "ping"
}

Response:

{
     "result": "PONG",
     "id": "123"
}

Step 5: Adding custom procedures to the rpc server

You can easily add methods to the rpc server:

Create any class that will implement Ufo\JsonRpcBundle\ApiMethod\Interfaces\IRpcService interface and implement any public method in that class

<?php

namespace MyBundle\RpcService;

use Ufo\JsonRpcBundle\ApiMethod\Interfaces\IRpcService;

class MyRpcProcedure implements IRpcService
{
     /**
      * @var string
      */
     const HELLO = 'Hello';

     /**
      * @return string
      */
     public function sayHello()
     {
         return static::HELLO;
     }

     /**
      * @param string $name
      * @return string
      */
     public function sayHelloName($name)
     {
         return static::HELLO . ', '. $name;
     }
}

Step 6: Profit

Make a GET request to the API to make sure your new methods are available:

GET /api:

{
     "transport": "POST",
     "envelope": "JSON-RPC-2.0",
     "contentType": "application/json",
     "SMDVersion": "2.0",
     "description": null,
     "target": "/api",
     "services": {
         "ping": {
             "envelope": "JSON-RPC-2.0",
             "transport": "POST",
             "name": "ping",
             "parameters": [],
             "returns": "string"
         },
         "MyRpcProcedure.sayHello": {
             "envelope": "JSON-RPC-2.0",
             "transport": "POST",
             "name": "ping",
             "parameters": [],
             "returns": "string"
         },
         "MyRpcProcedure.sayHelloName": {
             "envelope": "JSON-RPC-2.0",
             "transport": "POST",
             "name": "ping",
             "parameters": [
                 {
                     "type": "string",
                     "name": "name",
                     "optional": false
                 }
             ],
             "returns": "string"
         }
     },
     "methods": {
         "ping": {
             "envelope": "JSON-RPC-2.0",
             "transport": "POST",
             "name": "ping",
             "parameters": [],
             "returns": "string"
         },
         "MyRpcProcedure.sayHello": {
             "envelope": "JSON-RPC-2.0",
             "transport": "POST",
             "name": "ping",
             "parameters": [],
             "returns": "string"
         },
         "MyRpcProcedure.sayHelloName": {
             "envelope": "JSON-RPC-2.0",
             "transport": "POST",
             "name": "ping",
             "parameters": [
                 {
                     "type": "string",
                     "name": "name",
                     "optional": false
                 }
             ],
             "returns": "string"
         }
     }

}

And make test calls to your new methods:

POST /api

#1

Request:

{
     "id":123,
     "method": "MyRpcProcedure.sayHello"
}

Response:

{
     "result": "Hello",
     "id": "123"
}

#2

Request:

{
     "id":123,
     "method": "MyRpcProcedure.sayHelloName",
     "params": {
         "operation": "Mr. Anderson"
     }
}

Response:

{
     "result": "Hello, Mr. Anderson",
     "id": "123"
}

Step 7: Security

Security is disabled by default

The package supports client key validation.

To enable safe mode, you must add the appropriate settings to config/packages/ufo_api.yaml.

# config/packages/ufo_json_rpc.yaml
ufo_json_rpc:
    security:
        protected_methods: ['GET', 'POST']      # protection of GET and POST requests
        token_key_in_header: 'Ufo-RPC-Token'    # Name of the key in the header
        clients_tokens:
            - 'ClientTokenExample'              # hardcoded token example. Importantly!!! Replace or delete it!
            - '%env(resolve:UFO_API_TOKEN)%e'   # token example from .env.local

If secure mode is enabled, your requests must contain the header specified in token_key_in_header.

For example: Ufo-RPC-Token: ClientTokenExample

Integration of your RPC project with SoapUI

Your RPC project can be imported into a SoapUI application.

In order to do this, you need to import the remote project File -> Import Remote Project into SoupUI and specify the link to the xml export of your project http://example.com/api/soapui.xml . In SoupUI, you will receive a ready-made project with a list of all available methods.

The URL http://example.com/api/soapui.xml can accept the following optional query parameters:

  • token (string) client token for accessing your RPC project (it will be substituted in the SoupUI parameters of the project)
  • show_examples (boolean) takes the value 1|0 - substitute example values in methods (1 - by default) or specify parameter types (0)