docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api
en/docs/api/json-rpc-bundle/add_rpc_service/params.md
new file +152
ā0
1
+
# Method parameters
2
+
3
+
The parameters of an RPC method are the parameters of the PHP method. The bundle takes their names, types and default values from the signature and PHPDoc, builds a JSON Schema from them for the [documentation](/docs/api/json-rpc-bundle/documentation), and converts incoming values to the required types before the call.
4
+
5
+
## Scalar types
6
+
7
+
`string`, `int`, `float`, `bool`, `array`, `mixed` and their nullable/union variants are passed as is. A parameter with a default value (including `null`) is optional.
8
+
9
+
```php
10
+
public function search(string $query, int $limit = 20, ?string $sort = null): array
11
+
```
12
+
13
+
A wrong type or a missing required parameter returns error `-32602` with a list of problems for each parameter ā see [Error handling](/docs/api/json-rpc-bundle/error_handling).
14
+
15
+
## Exact types from PHPDoc
16
+
17
+
If the native type is not enough (`array`), the exact type is taken from `@param`. Class names are resolved through the `use` imports of the procedure class.
18
+
19
+
```php
20
+
/**
21
+
* @param OrderItemDto[] $items
22
+
* @param array<string, int|string> $meta
23
+
*/
24
+
public function save(array $items, array $meta = []): bool
25
+
```
26
+
27
+
## DTO
28
+
29
+
A parameter whose type is a class is automatically created from a JSON object:
30
+
31
+
```php
32
+
final class CreateOrderDto
33
+
{
34
+
public function __construct(
35
+
public string $sku,
36
+
public int $qty = 1,
37
+
) {}
38
+
}
39
+
40
+
public function create(CreateOrderDto $order): int
41
+
```
42
+
43
+
```json
44
+
{"jsonrpc": "2.0", "id": 1, "method": "Order.create", "params": {"order": {"sku": "A-1", "qty": 2}}}
45
+
```
46
+
47
+
* A DTO collection is described in PHPDoc (`@param CreateOrderDto[] $orders`) ā each array element becomes an object.
48
+
* For union types (`FooDto|BarDto`), the first DTO that could be created is used.
49
+
* A value from which a DTO cannot be created returns a validation error, not a raw array.
50
+
* In the DTO schema, properties with a default value get `default`, and only properties without one go into `required`.
51
+
52
+
## Automatic conversion
53
+
54
+
For parameters of the following types, the value is converted without additional attributes:
55
+
56
+
| Parameter type | What the client passes | Converter |
57
+
| --- | --- | --- |
58
+
| `BackedEnum` | case value (`"paid"`) | `BackedEnumConvertor` |
59
+
| pure enum | case name | `EnumConvertor` |
60
+
| `DateTime`, `DateTimeImmutable`, `DateTimeInterface` | date string | `DateTimeConverter` |
61
+
| `Symfony\Component\Uid\*`, `Ramsey\Uuid\*` | UUID string | `UuidConverter` |
62
+
| Doctrine entity | identifier | `DoctrineEntityConverter` |
63
+
64
+
```php
65
+
enum OrderStatus: string
66
+
{
67
+
case NEW = 'new';
68
+
case PAID = 'paid';
69
+
}
70
+
71
+
/**
72
+
* @param OrderStatus[] $statuses
73
+
*/
74
+
public function find(OrderStatus $status, array $statuses = []): array
75
+
76
+
// {"method": "Order.status", "params": {"order": 42}} ā Order is loaded by id
77
+
public function status(Order $order): string
78
+
```
79
+
80
+
`DoctrineEntityConverter` is registered only when DoctrineBundle is enabled.
81
+
82
+
In the response, these types are converted back to scalars: enum ā value, date ā string (`Y-m-d H:i:s`), UUID ā string, entity ā identifier (or `__toString()` for `Stringable`).
83
+
84
+
## `#[RPC\Param]`
85
+
86
+
The attribute explicitly sets which scalar types the parameter accepts and which converter transforms the value. It is needed when the type is not supported automatically or a different converter is required.
87
+
88
+
```php
89
+
public function __construct(
90
+
int $type, // bitmask Param::STRING | Param::INT | Param::FLOAT | Param::NULL
91
+
bool $collection = false, // the value is an array, each element is converted
92
+
array $context = [], // for example, [Param::C_CONVERTOR => MyConvertor::class]
93
+
)
94
+
```
95
+
96
+
```php
97
+
use Ufo\RpcObject\RPC;
98
+
99
+
public function charge(
100
+
#[RPC\Param(RPC\Param::STRING, context: [RPC\Param::C_CONVERTOR => MoneyConvertor::class])]
101
+
Money $amount,
102
+
): bool
103
+
```
104
+
105
+
Predefined masks: `Param::NUMBER`, `Param::NULLABLE_STRING`, `Param::NULLABLE_NUMBER`, `Param::MIXED`.
106
+
107
+
## Custom converter
108
+
109
+
Implement `Ufo\JsonRpcBundle\ParamConvertors\IParamConvertor`. With autoconfigure, the class automatically gets the `rpc.param_convertor` tag, and parameters of the supported type are converted without an attribute.
110
+
111
+
```php
112
+
use Ufo\JsonRpcBundle\ParamConvertors\IParamConvertor;
113
+
use Ufo\RpcObject\RPC\Param;
114
+
115
+
final class MoneyConvertor implements IParamConvertor
116
+
{
117
+
public function toScalar(object $object, array $context = [], ?callable $callback = null): array|string|int|float|null
118
+
{
119
+
return $object->amount;
120
+
}
121
+
122
+
public function toObject(int|string|float|null $value, array $context = [], ?callable $callback = null): ?object
123
+
{
124
+
return new Money((int) $value);
125
+
}
126
+
127
+
public function supported(string $classFQCN): bool
128
+
{
129
+
return $classFQCN === Money::class;
130
+
}
131
+
132
+
public function getParamAttr(string $classFQCN): Param
133
+
{
134
+
return new Param(Param::INT, context: [Param::C_CONVERTOR => self::class]);
135
+
}
136
+
}
137
+
```
138
+
139
+
## Special `$rpc` parameters
140
+
141
+
The `$rpc` object in `params` is not passed to the method; it controls how the request is executed:
142
+
143
+
| Key | Purpose |
144
+
| --- | --- |
145
+
| `callback` | URL to send the result to ā see [Webhook](/docs/api/json-rpc-bundle/functionality/callback) |
146
+
| `timeout` | Execution timeout, seconds (default 10) |
147
+
| `rayId` | Identifier of the parent request for tracing |
148
+
| `ignoreCache` | `true` ā bypass the [response cache](/docs/api/json-rpc-bundle/add_rpc_service/cache) and write it again |
149
+
150
+
```json
151
+
{"jsonrpc": "2.0", "id": 1, "method": "Orders.get", "params": {"id": 10, "$rpc": {"ignoreCache": true}}}
152
+
```