docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api
en/docs/api/json-rpc-bundle/add_rpc_service/README.md
new file +141
ā0
1
+
# Custom API methods
2
+
3
+
Any application class becomes an API service if it implements the `Ufo\JsonRpcBundle\ApiMethod\Interfaces\IRpcService` interface. The interface imposes no logic ā it only tags the class with `ufo.rpc.service`, which the bundle uses to build the method map when the container is compiled.
4
+
5
+
Every public non-static method of such a class (except the constructor) becomes a JSON-RPC method named `<class name>.<method>`.
6
+
7
+
```php
8
+
<?php
9
+
10
+
namespace App\Api;
11
+
12
+
use Ufo\JsonRpcBundle\ApiMethod\Interfaces\IRpcService;
13
+
use Ufo\RpcObject\RPC;
14
+
15
+
#[RPC\Info('Messenger')]
16
+
class MessengerApi implements IRpcService
17
+
{
18
+
public function __construct(private Mailer $mailer) {}
19
+
20
+
/**
21
+
* A method for sending an email message
22
+
* @param string $email The email address
23
+
* @param string $text Message body
24
+
* @param string $subject Optional message subject parameter
25
+
*/
26
+
public function sendEmail(string $email, string $text, string $subject = 'Message without subject'): bool
27
+
{
28
+
return $this->mailer->send($email, $subject, $text);
29
+
}
30
+
}
31
+
```
32
+
33
+
This example exposes the method `Messenger.sendEmail`:
34
+
35
+
::::columns
36
+
:::col
37
+
**Request**
38
+
```json
39
+
{
40
+
"jsonrpc": "2.0",
41
+
"id": 1,
42
+
"method": "Messenger.sendEmail",
43
+
"params": {
44
+
"email": "user@example.com",
45
+
"text": "Hello!"
46
+
}
47
+
}
48
+
```
49
+
:::
50
+
:::col
51
+
**Response**
52
+
```json
53
+
{
54
+
"jsonrpc": "2.0",
55
+
"id": 1,
56
+
"result": true
57
+
}
58
+
```
59
+
:::
60
+
::::
61
+
62
+
Parameters can also be passed positionally: `"params": ["user@example.com", "Hello!"]`.
63
+
64
+
:::info
65
+
The method map is built when the container is compiled. After adding or changing methods in `prod`, run `bin/console cache:clear`.
66
+
:::
67
+
68
+
## Naming
69
+
70
+
Without the attribute, the class name in the API is the short class name (`MessengerApi.sendEmail`). The [`#[RPC\Info]`](/docs/api/json-rpc-bundle/add_rpc_service/info) attribute sets an alias (`Messenger.sendEmail`), the separator character and the [API version](/docs/api/json-rpc-bundle/functionality/versions).
71
+
72
+
:::success subtitle="Good practice"
73
+
Treat the class name as a namespace and the method name as an action: `Cart.addProduct`, `Cart.getProducts`, `Messenger.sendEmail`, `Messenger.sendSms`. This way, methods with the same name in different classes do not conflict (`Product.create`, `User.create`), and the names make it clear what the server can do.
74
+
:::
75
+
76
+
## Describing methods and parameters
77
+
78
+
The documentation is built from everything known about the method: names, native types, default values and docblocks. The description of the method and its parameters is taken from PHPDoc, and the exact type comes from `@param` / `@return` when the native type is not enough:
79
+
80
+
```php
81
+
/**
82
+
* Creates an order
83
+
* @param OrderItemDto[] $items
84
+
* @return array<string, OrderItemDto>
85
+
*/
86
+
public function create(array $items, ?string $comment = null): array
87
+
```
88
+
89
+
A parameter with a `null` default or any other default value is optional. Types are covered in detail on the [Method parameters](/docs/api/json-rpc-bundle/add_rpc_service/params) page, the result in [Response format](/docs/api/json-rpc-bundle/add_rpc_service/response).
90
+
91
+
The method's name (`summary`) and description in the documentation can be translated without changing the code ā see [API documentation](/docs/api/json-rpc-bundle/documentation).
92
+
93
+
## Deprecated methods
94
+
95
+
A method with `@deprecated` in its docblock or with the `#[\Deprecated]` attribute is marked in OpenRPC as `"deprecated": true`, but keeps working.
96
+
97
+
```php
98
+
/**
99
+
* @deprecated use Orders.create
100
+
*/
101
+
public function createOrder(array $items): array
102
+
```
103
+
104
+
## Hiding a method from the API
105
+
106
+
Mark a public method that must not be an API method with `#[RPC\IgnoreApi]`: it appears neither in the method map nor in the documentation.
107
+
108
+
```php
109
+
#[RPC\IgnoreApi]
110
+
public function rebuildIndex(): void
111
+
```
112
+
113
+
## Services in method arguments
114
+
115
+
Besides constructor injection, a service can be received directly in a method argument via `#[Autowire]`. Such an argument is not an RPC parameter: it is not in the documentation, and the client does not pass it.
116
+
117
+
```php
118
+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
119
+
120
+
public function report(int $id, #[Autowire(service: 'app.report_builder')] ReportBuilder $builder): array
121
+
```
122
+
123
+
:::warning
124
+
In versions 10.0.1ā10.3.0, `#[Autowire]` in method arguments did not work (fixed in 10.3.1). On these versions, use the constructor.
125
+
:::
126
+
127
+
## RPC attributes
128
+
129
+
| Attribute | Where | Purpose |
130
+
| --- | --- | --- |
131
+
| [`#[RPC\Info]`](/docs/api/json-rpc-bundle/add_rpc_service/info) | class | Alias, separator, API version, removed methods |
132
+
| [`#[RPC\APIGroups]`](/docs/api/json-rpc-bundle/functionality/groups) | class, method | Which API groups the method belongs to |
133
+
| [`#[RPC\Assertions]`](/docs/api/json-rpc-bundle/add_rpc_service/assertions) | parameter | Validation with Symfony constraints |
134
+
| [`#[RPC\Param]`](/docs/api/json-rpc-bundle/add_rpc_service/params) | parameter | Explicit conversion of a value into an object |
135
+
| [`#[RPC\DTO]`](/docs/api/json-rpc-bundle/add_rpc_service/response) | method, property | DTO format for a result or parameter |
136
+
| [`#[RPC\Cache]`](/docs/api/json-rpc-bundle/add_rpc_service/cache) | method | Response caching |
137
+
| [`#[RPC\CacheRelation]`](/docs/api/json-rpc-bundle/add_rpc_service/cache) | method | Invalidation of related cache |
138
+
| [`#[RPC\Lock]`](/docs/api/json-rpc-bundle/add_rpc_service/lock) | method | Preventing concurrent calls |
139
+
| `#[RPC\IgnoreApi]` | method | Remove the method from the API |
140
+
141
+
All attributes come from the `ufo-tech/rpc-objects` package (namespace `Ufo\RpcObject\RPC`).