JSON-RPC 2.0 server for Symfony v.6.*
Package for easy api creation using json-rpc server
- 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"
}
- 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"
}
]
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
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.
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],
// ...
];
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
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!!!
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"
}
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;
}
}
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
Request:
{
"id":123,
"method": "MyRpcProcedure.sayHello"
}
Response:
{
"result": "Hello",
"id": "123"
}
Request:
{
"id":123,
"method": "MyRpcProcedure.sayHelloName",
"params": {
"operation": "Mr. Anderson"
}
}
Response:
{
"result": "Hello, Mr. Anderson",
"id": "123"
}
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
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)