docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api
uk/docs/api/rest-bundle/routing.md
новий файл +126
−0
1
+
# Маршрутизація
2
+
3
+
## Від `#[Route]` до REST-маршруту
4
+
5
+
Метод RPC-процедури потрапляє в REST, коли має атрибут `Symfony\Component\Routing\Attribute\Route`. Атрибут на класі необов'язковий і задає спільний шлях та назву. Методи без `#[Route]` лишаються лише в RPC.
6
+
7
+
| Частина | Правило |
8
+
| --- | --- |
9
+
| Шлях | шлях класу + `/` + шлях методу; порожній шлях методу дає шлях класу, обидва порожні — `/` |
10
+
| Назва | `ufo_rest_api_` + назва класу + `_` + назва методу |
11
+
| Назва класу | `name` з атрибута класу; без нього — псевдонім процедури з [`#[RPC\Info]`](/docs/api/json-rpc-bundle/add_rpc_service/info) у snake_case (`shopItems` → `shop_items`) |
12
+
| Назва методу | `name` з атрибута методу; без нього — назва PHP-методу в snake_case (`createItem` → `create_item`) |
13
+
| HTTP-методи | `methods` з атрибута методу; без них — `POST` |
14
+
| Інші параметри `#[Route]` | `requirements`, `defaults`, `host` тощо не використовуються: читаються лише `path`, `name` і `methods` |
15
+
16
+
```php
17
+
#[RPC\Info('catalog')]
18
+
#[Route('/catalog', name: 'catalog')]
19
+
class CatalogApi implements IRpcService
20
+
{
21
+
#[Route('/items/{id}', name: 'item', methods: ['GET'])] // GET /rest/catalog/items/{id}
22
+
public function item(int $id): array {}
23
+
24
+
#[Route('/items')] // POST /rest/catalog/items
25
+
public function createItem(string $title): array {}
26
+
}
27
+
```
28
+
29
+
Змінні шляху (`{id}`) передаються в метод як параметри з тією самою назвою — див. [Параметри запиту](/docs/api/rest-bundle/requests).
30
+
31
+
:::warning
32
+
Шлях не виводиться з назви RPC-методу автоматично: без `#[Route]` метод недоступний через REST, а невідомий шлях повертає `404`.
33
+
:::
34
+
35
+
## Згенеровані маршрути
36
+
37
+
Для кожного REST-методу і версії API створюються два маршрути Symfony:
38
+
39
+
| Маршрут | Шлях | HTTP-методи | Призначення |
40
+
| --- | --- | --- | --- |
41
+
| `<назва>_<версія>` | `<шлях>`, для версій, відмінних від `v1`, — `/<версія><шлях>` | з атрибута | Виклик методу |
42
+
| `<назва>_<версія>_method_not_allowed` | той самий | будь-які | Пріоритет `-10`: неправильний HTTP-метод отримує `405`, а не `404` |
43
+
44
+
Маршрути з `config/router.yaml` бандла:
45
+
46
+
| Маршрут | Шлях | Призначення |
47
+
| --- | --- | --- |
48
+
| `ufo_rest_doc` | префікс імпорту | OpenAPI, `GET` |
49
+
| `ufo_rest_doc_ver` | `/{ver}` (`v\d+`) | OpenAPI для версії |
50
+
| `ufo_rest_doc_postman` | `/postman` | Postman |
51
+
| `ufo_rest_doc_postman_ver` | `/{ver}/postman` | Postman для версії |
52
+
| `ufo_rest_api_entrypoint` | `/{path}` | Загальний вхід, пріоритет `-100`: невідомий шлях повертає `404` у форматі [помилок](/docs/api/rest-bundle/error_handling) |
53
+
| `ufo_rest_api_entrypoint_ver` | `/{ver}/{path}` | Те саме для версій, пріоритет `-90` |
54
+
55
+
`HEAD` обробляється маршрутами `GET`. `OPTIONS` окремо не обробляється: для методу без `OPTIONS` у `methods` відповідь — `405`.
56
+
57
+
## Версії
58
+
59
+
Версії задає JsonRpcBundle: `#[RPC\Info(version: 2, removedMethods: [...])]` ([Версії API](/docs/api/json-rpc-bundle/functionality/versions)). Процедура версії 2 успадковує методи версії 1, які не перевизначає і не прибирає.
60
+
61
+
| Версія | Виклик | Документація | Назва маршруту |
62
+
| --- | --- | --- | --- |
63
+
| `v1` (за замовчуванням) | `/rest/catalog/items/1` | `/rest`, `/rest/postman` | `..._v1` |
64
+
| `v2` | `/rest/v2/catalog/items/1` | `/rest/v2`, `/rest/v2/postman` | `..._v2` |
65
+
66
+
Невідома версія повертає `404`.
67
+
68
+
## Групи API та кілька входів
69
+
70
+
Імпортуйте `config/router.yaml` окремо для кожного входу. `defaults.api_group` вибирає [групу API](/docs/api/json-rpc-bundle/functionality/groups); без нього група — `general`. Префікс URL від назви групи не залежить.
71
+
72
+
```yaml
73
+
# config/routes/ufo_rest_api.yaml
74
+
rest:
75
+
resource: ../../vendor/ufo-tech/rest-bundle/config/router.yaml
76
+
prefix: /rest
77
+
trailing_slash_on_root: false
78
+
79
+
rest_internal:
80
+
resource: ../../vendor/ufo-tech/rest-bundle/config/router.yaml
81
+
prefix: /internal
82
+
defaults: { api_group: internal }
83
+
trailing_slash_on_root: false
84
+
85
+
rest_partners:
86
+
resource: ../../vendor/ufo-tech/rest-bundle/config/router.yaml
87
+
prefix: /partners
88
+
name_prefix: partners_
89
+
defaults: { api_group: internal }
90
+
trailing_slash_on_root: false
91
+
```
92
+
93
+
```php
94
+
#[RPC\Info('catalog')]
95
+
#[RPC\APIGroups(['internal', 'public'], false)]
96
+
#[Route('/catalog', name: 'catalog')]
97
+
class CatalogApi implements IRpcService
98
+
{
99
+
#[Route('/list', name: 'list', methods: ['GET'])]
100
+
public function list(): array { return []; }
101
+
102
+
#[RPC\APIGroups(['internal'], false)]
103
+
#[Route('/price', name: 'price', methods: ['POST'])]
104
+
public function price(int $price): int { return $price; }
105
+
}
106
+
```
107
+
108
+
* Належність методу до груп визначає `#[RPC\APIGroups]`: атрибут методу замінює атрибут класу, `withDefault: true` додає `general`. `#[RPC\IgnoreApi]` повністю виключає метод. Щоб метод з'явився в REST, `#[Route]` потрібен однаково.
109
+
* Кожен вхід має власні методи, версії, документацію і провайдер токенів.
110
+
* Назви маршрутів отримують префікс групи: `internal_ufo_rest_doc`, `internal_ufo_rest_api_catalog_list_v1`. `name_prefix` іде після нього: `internal_partners_ufo_rest_doc`.
111
+
* Маршрути групи `general` зберігають і старі назви як псевдоніми: `ufo_rest_doc` → `general_ufo_rest_doc`.
112
+
* Групу визначає лише маршрут: поле `api_group` у query чи тілі запиту її не змінює.
113
+
114
+
## Поруч з RPC та іншими адаптерами
115
+
116
+
Маршрути REST реєструються через `Ufo\JsonRpcBundle\Routing\IApiRouteImport` (клас `RestRouteImport`), тож обробку груп і назв виконує завантажувач маршрутів JsonRpcBundle. RPC-, REST- і маршрути інших адаптерів, що реалізують той самий інтерфейс, можна імпортувати для тих самих груп в одному файлі без конфліктів назв.
117
+
118
+
:::info
119
+
У 1.1–1.2 для цього використовувався власний завантажувач `RestYamlFileLoader`; у 1.3 його видалено (див. [Історію змін](/docs/api/rest-bundle/change_log)). Застосунків, що лише імпортують `config/router.yaml`, це не стосується.
120
+
:::
121
+
122
+
## Діагностика
123
+
124
+
* **Методу немає в REST** — перевірте `#[Route]` на методі, групу API імпорту, `#[RPC\IgnoreApi]` і `removedMethods` версії.
125
+
* **`405` для наявного методу** — HTTP-методу немає в `methods` атрибута (за замовчуванням — лише `POST`).
126
+
* **Назви маршрутів** — `bin/console debug:router | grep ufo_rest`.