Зміни в документі Версія 6: Налаштування

Остання зміна 2024/07/11 10:07 автором Ashterix

Від версії 21.2
редаговано Ashterix
дата 2024/05/16 11:27
Змінити коментар: Немає коментарів для цієї версії
До версії 22.1
редаговано Ashterix
дата 2024/05/16 11:32
Змінити коментар: Немає коментарів для цієї версії

Підсумок

Подробиці

Властивості сторінки
Вміст
... ... @@ -1,18 +1,37 @@
1 -{{box cssClass="floatinginfobox" title="**Зміст**"}}
2 -{{toc/}}
3 -{{/box}}
1 +(% class="box floatinginfobox" %)
2 +(((
3 +**Зміст**
4 4  
5 +(% class="wikitoc" %)
6 +* [[Блок security>>path:#H41143B43E43AA0]]
7 +** [[Параметр protected_methods>>path:#H41F43044043043C435442440]]
8 +** [[Параметр token_key_in_header>>path:#H41F43044043043C435442440-1]]
9 +** [[Параметр clients_tokens>>path:#H41F43044043043C435442440-2]]
10 +*** [[Токени в параметрах>>path:#H42243E43A43543D43843243F43044043043C435442440430445]]
11 +*** [[Токени в змінних оточення>>path:#H42243E43A43543D43843243743C45643D43D43844543E44243E44743543D43D44F]]
12 +*** [[Токени для користувача>>path:#H42243E43A43543D43843443B44F43A43E440438441442443432430447430]]
13 +**** [[Приклад власного валідатора токенів>>path:#H41F44043843A43B43043443243B43044143D43E43343E43243043B45643443044243E44043044243E43A43543D456432]]
14 +* [[Блок async>>path:#H41143B43E43AA0-1]]
15 +* [[Блок docs>>path:#H41143B43E43AA0-2]]
16 +** [[Секція response>>path:#H42143543A44645644F]]
17 +*** [[Параметр key_for_methods>>path:#H41F43044043043C435442440A0]]
18 +*** [[Параметр async_dsn_info>>path:#H41F43044043043C435442440A0-1]]
19 +**** [[Приклад документації >>path:#H41F44043843A43B43043443443E43A44343C43543D442430446456457]]
20 +*** [[Параметр validations>>path:#H41F43044043043C435442440A0-2]]
21 +**** [[Приклад документації >>path:#H41F44043843A43B43043443443E43A44343C43543D442430446456457-1]]
22 +)))
23 +
5 5  (% class="wikigeneratedid" %)
6 -Всі налаштування бандла знаходяться в файлі {{code language="none"}}config/packages/ufo_json_rpc.yaml{{/code}}.
25 +Всі налаштування бандла знаходяться в файлі (% class="box code" %)config/packages/ufo_json_rpc.yaml(%%).
7 7  
8 8  (% class="wikigeneratedid" %)
9 9  Є можливість налаштувати параметри захисту API та деякі параметри формату даних, що віддається при запиті документації.
10 10  
11 -= Блок {{code language="none"}}security{{/code}} =
30 += Блок (% class="box code" %)security(%%) =
12 12  
13 13  Наразі єдиним механізмом захисту доступу до вашого API є встановлення перевірки ключа доступу (api_token).
14 14  
15 -== Параметр {{code language="none"}}protected_methods{{/code}} ==
34 +== Параметр (% class="box code" %)protected_methods(%%) ==
16 16  
17 17  (% class="wikigeneratedid" %)
18 18  Цей параметр приймає масив назв http методів, які мають бути захищені.
... ... @@ -20,31 +20,77 @@
20 20  (% class="wikigeneratedid" %)
21 21  За замовченням ввімкнут захист лише для методу POST. Ви можете:
22 22  
23 -* вказати пустий масив {{code language="none"}}[]{{/code}} щоб зробити API повністю відкритим
42 +* вказати пустий масив (% class="box code" %)[](%%) щоб зробити API повністю відкритим
24 24  
25 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
26 -ufo_json_rpc:
27 - security:
28 - protected_methods: []
29 -{{/code}}
44 +(% class="box" %)
45 +(((
46 +config/packages/ufo_json_rpc.yaml
30 30  
48 +(% class="code" %)
49 +(((
50 +(% class="linenoswrapper" %)
51 +(((
52 +(% class="linenos" %)
53 +(((
54 +1
55 +2
56 +3\\
57 +)))
58 +
59 +(((
60 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
61 + (% style="font-weight: bold; color: #008000;" %)security(%%):
62 + (% style="font-weight: bold; color: #008000;" %)protected_methods(%%): []
63 +)))
64 +)))
65 +)))
66 +)))
67 +
31 31  * вказати додатково захист для методу GET, що зробить запит документації недоступним без токену в заголовках запиту
32 32  
33 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
34 -ufo_json_rpc:
35 - security:
36 - protected_methods: ['GET', 'POST']
37 -{{/code}}
70 +(% class="box" %)
71 +(((
72 +config/packages/ufo_json_rpc.yaml
38 38  
39 -(% id="cke_bm_164641S" style="display:none" %) (%%)Якщо ви захищаєте ваш API через {{code language="none"}}protected_methods{{/code}}, вам необхідно налаштувати токени, по яким буде відкритий доступ.
74 +(% class="code" %)
75 +(((
76 +(% class="linenoswrapper" %)
77 +(((
78 +(% class="linenos" %)
79 +(((
80 +1
81 +2
82 +3\\
83 +)))
40 40  
85 +(((
86 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
87 + (% style="font-weight: bold; color: #008000;" %)security(%%):
88 + (% style="font-weight: bold; color: #008000;" %)protected_methods(%%): [(% style="color: #BA2121;" %)'GET'(%%), (% style="color: #BA2121;" %)'POST'(%%)]
89 +)))
90 +)))
91 +)))
92 +)))
93 +
94 +(% id="cke_bm_164641S" style="display:none" %) (%%)Якщо ви захищаєте ваш API через (% class="box code" %)protected_methods(%%), вам необхідно налаштувати токени, по яким буде відкритий доступ.
95 +
41 41  Перш за все, треба визначитися з назвою токену.
42 42  
43 -== Параметр {{code language="none"}}token_key_in_header{{/code}} ==
98 +== Параметр (% class="box code" %)token_key_in_header(%%) ==
44 44  
45 -Компонент {{code language="none"}}RpcSecurity{{/code}} буде шукати в заголовках запиту специфічний ключ, який ви можете встановити в налаштуваннях пакету, значення за замовченням {{code language="none"}}token_key_in_header: 'Ufo-RPC-Token'{{/code}}, ви можете встановити будь-яке інше значення яке відповідає наступним вимогам.
100 +Компонент (% class="box code" %)RpcSecurity(%%) буде шукати в заголовках запиту специфічний ключ, який ви можете встановити в налаштуваннях пакету, значення за замовченням (% class="box code" %)token_key_in_header: 'Ufo-RPC-Token'(%%), ви можете встановити будь-яке інше значення яке відповідає наступним вимогам.
46 46  
47 -{{spoiler title=" Вимоги до формування заголовків протоколу HTTP"}}
102 +\\
103 +
104 +(% class="spoiler" %)
105 +(((
106 +(% class="spoilerTitle" %)
107 +(((
108 +Вимоги до формування заголовків протоколу HTTP
109 +)))
110 +
111 +(% class="spoilerContent hidden" %)
112 +(((
48 48  Вимоги до назв заголовків HTTP не є строго регульованими щодо капіталізації, оскільки HTTP заголовки нечутливі до регістру. Однак, існують деякі загальні практики і стандарти, які зазвичай дотримуються для кращої читабельності та узгодженості:
49 49  
50 50  - Капіталізація: Зазвичай назви HTTP заголовків пишуться з використанням CamelCase, де кожне слово починається з великої літери, наприклад, Content-Type, User-Agent, Accept-Encoding. Це не впливає на технічну обробку заголовків, але робить їх легше читати.
... ... @@ -51,13 +51,15 @@
51 51  - Унікальність: Кожен заголовок повинен мати унікальну назву у контексті одного HTTP запиту або відповіді. Не можна використовувати однакові назви для різних заголовків у тому самому запиті чи відповіді.
52 52  - Спеціальні заголовки: Існують заголовки, які використовуються специфічно для контролю поведінки кешування (Cache-Control), безпеки (Strict-Transport-Security), аутентифікації (Authorization), тощо.
53 53  - Норми RFC: Вимоги до заголовків регулюються документами RFC, які визначають стандарти для протоколів Інтернету. Наприклад, загальні заголовки і їхнє використання описані в RFC 7231.
54 -{{/spoiler}}
119 +)))
120 +)))
55 55  
56 56  
57 57  
58 58  
59 -== Параметр {{code language="none"}}clients_tokens{{/code}} ==
60 60  
126 +== Параметр (% class="box code" %)clients_tokens(%%) ==
127 +
61 61  Тепер слід вказати масив клієнтськіх токенів, які будуть мати доступ до API.
62 62  
63 63  Тут є певна варіативність.
... ... @@ -74,352 +74,780 @@
74 74  
75 75  Це погано з позиції безпеки, якщо код зберігається в публічному репозиторію, то до цього токену буде мати доступ кожен.
76 76  
77 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
78 -ufo_json_rpc:
79 - security:
80 - protected_methods: ['GET', 'POST']
81 - token_key_in_header: 'Ufo-RPC-Token'
82 - clients_tokens:
83 - - 'ClientTokenExample' # hardcoded token example. Importantly!!! Replace or delete it!
144 +(% class="box" %)
145 +(((
146 +config/packages/ufo_json_rpc.yaml
147 +
148 +(% class="code" %)
149 +(((
150 +(% class="linenoswrapper" %)
151 +(((
152 +(% class="linenos" %)
153 +(((
154 +1
155 +2
156 +3
157 +4
158 +5
159 +6
160 +7\\
161 +)))
162 +
163 +(((
164 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
165 + (% style="font-weight: bold; color: #008000;" %)security(%%):
166 + (% style="font-weight: bold; color: #008000;" %)protected_methods(%%): [(% style="color: #BA2121;" %)'GET'(%%), (% style="color: #BA2121;" %)'POST'(%%)]
167 + (% style="font-weight: bold; color: #008000;" %)token_key_in_header(%%): (% style="color: #BA2121;" %)'Ufo-RPC-Token'(%%)
168 + (% style="font-weight: bold; color: #008000;" %)clients_tokens(%%):
169 + - (% style="color: #BA2121;" %)'ClientTokenExample'(%%) (% style="font-style: italic; color: #408080;" %)# hardcoded token example. Importantly!!! Replace or delete it!(%%)
84 84  
85 -{{/code}}
171 +)))
172 +)))
173 +)))
174 +)))
86 86  
87 87  === Токени в змінних оточення ===
88 88  
89 89  Це найбільш доцільний механізм у разі, якщо ви розробляєте сервіс для розподіленого бекенду, що написаний на SOA (Сервіс-Орієнтована Архітектура). Зазвичай, в такому випадку, вам треба відкрити доступ до апі одному або обмеженій кількості клієнтських додатків і оновлення ключів не буде відбуватися занадто часто.
90 90  
91 -В такому випадку можна прописати токени в змінних оточення (файл {{code language="none"}}.env.local{{/code}} під час локальної розробки). Цей механізм достатньо безпечний з боку збереження доступів.
180 +В такому випадку можна прописати токени в змінних оточення (файл (% class="box code" %).env.local(%%) під час локальної розробки). Цей механізм достатньо безпечний з боку збереження доступів.
92 92  
93 93  (((
94 -{{code language="ini" layout="LINENUMBERS" title=".env.local"}}
95 -TOKEN_FOR_APP_1=9363074966579432364f8b73b3318f71
96 -TOKEN_FOR_APP_2=456fg87g8h98jmnb8675r4445n8up365
97 -{{/code}}
183 +(% class="box" %)
184 +(((
185 +.env.local
98 98  
99 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
100 -ufo_json_rpc:
101 - security:
102 - protected_methods: ['GET', 'POST']
103 - token_key_in_header: 'Ufo-RPC-Token'
104 - clients_tokens:
105 - - '%env(resolve:TOKEN_FOR_APP_1)%' # token example from .env.local
106 - - '%env(resolve:TOKEN_FOR_APP_2)%' # token example from .env.local
107 -{{/code}}
187 +(% class="code" %)
188 +(((
189 +(% class="linenoswrapper" %)
190 +(((
191 +(% class="linenos" %)
192 +(((
193 +1
194 +2\\
108 108  )))
109 109  
197 +(((
198 +(% style="color: #7D9029;" %)TOKEN_FOR_APP_1(% style="color: #666666;" %)=(% style="color: #BA2121;" %)9363074966579432364f8b73b3318f71(%%)
199 +(% style="color: #7D9029;" %)TOKEN_FOR_APP_2(% style="color: #666666;" %)=(% style="color: #BA2121;" %)456fg87g8h98jmnb8675r4445n8up365
200 +)))
201 +)))
202 +)))
203 +)))
204 +
205 +(% class="box" %)
206 +(((
207 +config/packages/ufo_json_rpc.yaml
208 +
209 +(% class="code" %)
210 +(((
211 +(% class="linenoswrapper" %)
212 +(((
213 +(% class="linenos" %)
214 +(((
215 +1
216 +2
217 +3
218 +4
219 +5
220 +6
221 +7\\
222 +)))
223 +
224 +(((
225 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
226 + (% style="font-weight: bold; color: #008000;" %)security(%%):
227 + (% style="font-weight: bold; color: #008000;" %)protected_methods(%%): [(% style="color: #BA2121;" %)'GET'(%%), (% style="color: #BA2121;" %)'POST'(%%)]
228 + (% style="font-weight: bold; color: #008000;" %)token_key_in_header(%%): (% style="color: #BA2121;" %)'Ufo-RPC-Token'(%%)
229 + (% style="font-weight: bold; color: #008000;" %)clients_tokens(%%):
230 + - (% style="color: #BA2121;" %)'%env(resolve:TOKEN_FOR_APP_1)%'(%%) (% style="font-style: italic; color: #408080;" %)# token example from .env.local(%%)
231 + - (% style="color: #BA2121;" %)'%env(resolve:TOKEN_FOR_APP_2)%'(%%) (% style="font-style: italic; color: #408080;" %)# token example from .env.local
232 +)))
233 +)))
234 +)))
235 +)))
236 +)))
237 +
110 110  === Токени для користувача ===
111 111  
112 112  Припускаю, що у вас може виникнути потреба зробити персональні ключі для користувачів вашого додатку, можливо ви захочете впровадити ліміти або інші обмеження.
113 113  В такому випадку вам не потрібно вказувати перелік токенів в конфігах, ви можете зберігати їх в базі даних або іншому місці згідно вашій бізнес-логіки. Єдина вимога, у вас має бути сервіс, який вміє перевіряти чи існує наданий токен.
114 114  
115 -Для того, щоб JsonRpcServer міг використовувати вашу логіку, доведеться реалізувати власний клас, що реалізує інтерфейс {{code language="none"}}Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator{{/code}}
243 +Для того, щоб JsonRpcServer міг використовувати вашу логіку, доведеться реалізувати власний клас, що реалізує інтерфейс (% class="box code" %)Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator
116 116  
117 -{{code language="php" layout="LINENUMBERS" title="==== Приклад власного валідатора токенів ===="}}
118 -<?php
245 +(% class="box" %)
246 +(((
247 +==== Приклад власного валідатора токенів ====
119 119  
120 -namespace App\Services\RpcSecurity;
249 +(% class="code" %)
250 +(((
251 +(% class="linenoswrapper" %)
252 +(((
253 +(% class="linenos" %)
254 +(((
255 +1
256 +2
257 +3
258 +4
259 +5
260 +6
261 +7
262 +8
263 +9
264 +10
265 +11
266 +12
267 +13
268 +14
269 +15
270 +16
271 +17
272 +18
273 +19
274 +20
275 +21
276 +22
277 +23
278 +24\\
279 +)))
121 121  
122 -use App\Services\UserService;
123 -use Symfony\Component\Security\Core\Exception\UserNotFoundException;
124 -use Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator;
125 -use Ufo\RpcError\RpcInvalidTokenException;
126 -
127 -class UserTokenValidator implements ITokenValidator
281 +(((
282 +(% style="color: #BC7A00;" %)<?php(%%)
283 +\\(% style="font-weight: bold; color: #008000;" %)namespace(%%) App\Services\RpcSecurity;
284 +\\(% style="font-weight: bold; color: #008000;" %)use(%%) App\Services\UserService;
285 +(% style="font-weight: bold; color: #008000;" %)use(%%) Symfony\Component\Security\Core\Exception\UserNotFoundException;
286 +(% style="font-weight: bold; color: #008000;" %)use(%%) Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator;
287 +(% style="font-weight: bold; color: #008000;" %)use(%%) Ufo\RpcError\RpcInvalidTokenException;
288 +\\(% style="font-weight: bold; color: #008000;" %)class(%%) (% style="font-weight: bold; color: #0000FF;" %)UserTokenValidator(%%) (% style="font-weight: bold; color: #008000;" %)implements(%%) ITokenValidator
128 128  {
129 -
130 - public function __construct(protected UserService $userService) {}
131 -
132 - public function isValid(string $token): true
290 +\\ (% style="font-weight: bold; color: #008000;" %)public(%%) (% style="font-weight: bold; color: #008000;" %)function(%%) (% style="color: #0000FF;" %)~_~_construct(%%)((% style="font-weight: bold; color: #008000;" %)protected(%%) UserService (% style="color: #19177C;" %)$userService(%%)) {}
291 +\\ (% style="font-weight: bold; color: #008000;" %)public(%%) (% style="font-weight: bold; color: #008000;" %)function(%%) (% style="color: #0000FF;" %)isValid(%%)(string (% style="color: #19177C;" %)$token(%%))(% style="color: #666666;" %):(%%) (% style="font-weight: bold; color: #008000;" %)true(%%)
133 133   {
134 - try {
135 - $this->userService->getUserByToken($token);
136 - return true;
137 - } catch (UserNotFoundException $e) {
138 - throw new RpcInvalidTokenException(previous: $e);
293 + (% style="font-weight: bold; color: #008000;" %)try(%%) {
294 + (% style="color: #19177C;" %)$this(% style="color: #666666;" %)->(% style="color: #7D9029;" %)userService(% style="color: #666666;" %)->(% style="color: #7D9029;" %)getUserByToken(%%)((% style="color: #19177C;" %)$token(%%));
295 + (% style="font-weight: bold; color: #008000;" %)return(%%) (% style="font-weight: bold; color: #008000;" %)true(%%);
296 + } (% style="font-weight: bold; color: #008000;" %)catch(%%) (UserNotFoundException (% style="color: #19177C;" %)$e(%%)) {
297 + (% style="font-weight: bold; color: #008000;" %)throw(%%) (% style="font-weight: bold; color: #008000;" %)new(%%) RpcInvalidTokenException(previous(% style="color: #666666;" %):(%%) (% style="color: #19177C;" %)$e(%%));
139 139   }
140 140   }
141 141  }
142 -{{/code}}
301 +)))
302 +)))
303 +)))
304 +)))
143 143  
144 144  (% class="box warningmessage" %)
145 145  (((
146 146  **ВАЖЛИВО!!!**
147 -Метод {{code language="none"}}isValid{{/code}} має повертати {{code language="none"}}true{{/code}} якщо токен існує і валідний, або викидати {{code language="none"}}Ufo\RpcError\RpcInvalidTokenException{{/code}} в іншому разі.
309 +Метод (% class="box code" %)isValid(%%) має повертати (% class="box code" %)true(%%) якщо токен існує і валідний, або викидати (% class="box code" %)Ufo\RpcError\RpcInvalidTokenException(%%) в іншому разі.
148 148  )))
149 149  
150 -Після цього вам потрібно в файлі {{code language="none"}}config/services.yaml{{/code}} прописати що класи, що мають залежність від інтерфейса {{code language="none"}}ITokenValidator{{/code}} мають приймати ваш новий клас.
312 +Після цього вам потрібно в файлі (% class="box code" %)config/services.yaml(%%) прописати що класи, що мають залежність від інтерфейса (% class="box code" %)ITokenValidator(%%) мають приймати ваш новий клас.
151 151  
152 -{{code language="yaml" layout="LINENUMBERS" title="config/services.yaml"}}
153 -parameters:
154 - # some parameters list
155 - # ...
314 +(% class="box" %)
315 +(((
316 +config/services.yaml
156 156  
157 -services:
158 - # some services list
159 - # ...
318 +(% class="code" %)
319 +(((
320 +(% class="linenoswrapper" %)
321 +(((
322 +(% class="linenos" %)
323 +(((
324 +1
325 +2
326 +3
327 +4
328 +5
329 +6
330 +7
331 +8
332 +9
333 +10\\
334 +)))
160 160  
161 - Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator:
162 - class: App\Services\RpcSecurity\UserTokenValidator
163 -{{/code}}
336 +(((
337 +(% style="font-weight: bold; color: #008000;" %)parameters(%%):
338 + (% style="font-style: italic; color: #408080;" %)# some parameters list(%%)
339 + (% style="font-style: italic; color: #408080;" %)# ...(%%)
340 +\\(% style="font-weight: bold; color: #008000;" %)services(%%):
341 + (% style="font-style: italic; color: #408080;" %)# some services list(%%)
342 + (% style="font-style: italic; color: #408080;" %)# ...(%%)
343 +\\ (% style="font-weight: bold; color: #008000;" %)Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator(%%):
344 + (% style="font-weight: bold; color: #008000;" %)class(%%): App\Services\RpcSecurity\UserTokenValidator
345 +)))
346 +)))
347 +)))
348 +)))
164 164  
165 -= Блок {{code language="none"}}async{{/code}} =
350 += Блок (% class="box code" %)async(%%) =
166 166  
167 -Цей блок для налаштування [[асинхронного транспорту>>doc:.functionality.async.WebHome]].
352 +Цей блок для налаштування [[асинхронного транспорту>>path:/bin/view/docs/JsonRpcBundle/functionality/async/]].
168 168  
169 -Додайте параметр {{code language="none"}}rpc_async{{/code}} який містить рядок у форматі DSN. Цей рядок є конфігурацією [[Symfony Messenger>>https://symfony.com/doc/current/messenger.html]], він вказує на асинхронний транспорт по якому RPC Server буде очікувати вхідні запити якщо у вас запущений консюмер ({{code language="none"}}php bin/console messenger:consume rpc_async{{/code}}). Для більш детального розуміння цього процесу читайте документацію [[Symfony Messenge>>https://symfony.com/doc/current/messenger.html]].
354 +Додайте параметр (% class="box code" %)rpc_async(%%) який містить рядок у форматі DSN. Цей рядок є конфігурацією [[Symfony Messenger>>url:https://symfony.com/doc/current/messenger.html]], він вказує на асинхронний транспорт по якому RPC Server буде очікувати вхідні запити якщо у вас запущений консюмер ((% class="box code" %)php bin/console messenger:consume rpc_async(%%)). Для більш детального розуміння цього процесу читайте документацію [[Symfony Messenge>>url:https://symfony.com/doc/current/messenger.html]].
170 170  
171 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
172 -ufo_json_rpc:
173 - async:
174 - rpc_async: '%env(resolve:RPC_TRANSPORT_DSN)%'
356 +(% class="box" %)
357 +(((
358 +config/packages/ufo_json_rpc.yaml
175 175  
176 -{{/code}}
360 +(% class="code" %)
361 +(((
362 +(% class="linenoswrapper" %)
363 +(((
364 +(% class="linenos" %)
365 +(((
366 +1
367 +2
368 +3
369 +4\\
370 +)))
177 177  
372 +(((
373 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
374 + (% style="font-weight: bold; color: #008000;" %)async(%%):
375 + (% style="font-weight: bold; color: #008000;" %)rpc_async(%%): (% style="color: #BA2121;" %)'%env(resolve:RPC_TRANSPORT_DSN)%'(%%)\\
376 +)))
377 +)))
378 +)))
379 +)))
380 +
178 178  (% class="box warningmessage" %)
179 179  (((
180 180  Це налаштування має на увазі, що у вас в змінних оточення встановлена змінна RPC_TRANSPORT_DSN що містить DSN рядок.
181 181  )))
182 182  
183 -= Блок {{code language="none"}}docs{{/code}} =
386 += Блок (% class="box code" %)docs(%%) =
184 184  
185 185  Це блок який налаштовує генерацію документації коли ви робите GET запит на RPC Server
186 186  
187 -== Секція {{code language="none"}}response{{/code}} ==
390 +== Секція (% class="box code" %)response(%%) ==
188 188  
189 189  Містить налаштування, що відповідають за вміст відповіді.
190 190  
191 -=== Параметр {{code language="none"}}key_for_methods{{/code}} ===
394 +=== Параметр (% class="box code" %)key_for_methods(%%) ===
192 192  
193 193  Цей параметр дозволяє вказати назву ключа у відповіді в якій буде віддаватися масив доступних сервісів.
194 194  
195 -Значення за замовченням {{code language="none"}}methods{{/code}}. Може мати будь-яке значення типу рядок.
398 +Значення за замовченням (% class="box code" %)methods(%%). Може мати будь-яке значення типу рядок.
196 196  
197 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
198 -ufo_json_rpc:
199 - docs:
200 - key_for_methods: methods
201 -{{/code}}
400 +(% class="box" %)
401 +(((
402 +config/packages/ufo_json_rpc.yaml
202 202  
203 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
204 -ufo_json_rpc:
205 - docs:
206 - key_for_methods: services
207 -{{/code}}
404 +(% class="code" %)
405 +(((
406 +(% class="linenoswrapper" %)
407 +(((
408 +(% class="linenos" %)
409 +(((
410 +1
411 +2
412 +3\\
413 +)))
208 208  
209 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
210 -ufo_json_rpc:
211 - docs:
212 - key_for_methods: some_custom_key
213 -{{/code}}
415 +(((
416 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
417 + (% style="font-weight: bold; color: #008000;" %)docs(%%):
418 + (% style="font-weight: bold; color: #008000;" %)key_for_methods(%%): methods
419 +)))
420 +)))
421 +)))
422 +)))
214 214  
215 -=== Параметр {{code language="none"}}async_dsn_info{{/code}} ===
424 +(% class="box" %)
425 +(((
426 +config/packages/ufo_json_rpc.yaml
216 216  
428 +(% class="code" %)
429 +(((
430 +(% class="linenoswrapper" %)
431 +(((
432 +(% class="linenos" %)
433 +(((
434 +1
435 +2
436 +3\\
437 +)))
438 +
439 +(((
440 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
441 + (% style="font-weight: bold; color: #008000;" %)docs(%%):
442 + (% style="font-weight: bold; color: #008000;" %)key_for_methods(%%): services
443 +)))
444 +)))
445 +)))
446 +)))
447 +
448 +(% class="box" %)
449 +(((
450 +config/packages/ufo_json_rpc.yaml
451 +
452 +(% class="code" %)
453 +(((
454 +(% class="linenoswrapper" %)
455 +(((
456 +(% class="linenos" %)
457 +(((
458 +1
459 +2
460 +3\\
461 +)))
462 +
463 +(((
464 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
465 + (% style="font-weight: bold; color: #008000;" %)docs(%%):
466 + (% style="font-weight: bold; color: #008000;" %)key_for_methods(%%): some_custom_key
467 +)))
468 +)))
469 +)))
470 +)))
471 +
472 +=== Параметр (% class="box code" %)async_dsn_info(%%) ===
473 +
217 217  Відповідає за відображення в документації інформації про асинхронний транспорт.
218 218  
219 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
220 -ufo_json_rpc:
221 - async_dsn_info: true # or false
222 -{{/code}}
476 +(% class="box" %)
477 +(((
478 +config/packages/ufo_json_rpc.yaml
223 223  
480 +(% class="code" %)
481 +(((
482 +(% class="linenoswrapper" %)
483 +(((
484 +(% class="linenos" %)
485 +(((
486 +1
487 +2\\
488 +)))
489 +
490 +(((
491 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
492 + (% style="font-weight: bold; color: #008000;" %)async_dsn_info(%%): true (% style="font-style: italic; color: #408080;" %)# or false
493 +)))
494 +)))
495 +)))
496 +)))
497 +
224 224  ==== **Приклад документації ** ====
225 225  
226 -{{code language="json" layout="LINENUMBERS" title="GET: /api"}}
500 +(% class="box" %)
501 +(((
502 +GET: /api
503 +
504 +(% class="code" %)
505 +(((
506 +(% class="linenoswrapper" %)
507 +(((
508 +(% class="linenos" %)
509 +(((
510 +1
511 +2
512 +3
513 +4
514 +5
515 +6
516 +7
517 +8
518 +9
519 +10
520 +11
521 +12
522 +13
523 +14
524 +15
525 +16
526 +17
527 +18
528 +19
529 +20
530 +21
531 +22
532 +23
533 +24\\
534 +)))
535 +
536 +(((
227 227  {
228 - "envelope": "JSON-RPC-2.0/UFO-RPC-6",
229 - "contentType": "application/json",
230 - "description": "",
231 - "transport": {
232 - "sync": {
233 - "scheme": "http",
234 - "host": "example.com",
235 - "path": "/api",
236 - "method": "POST"
538 + (% style="font-weight: bold; color: #008000;" %)"envelope"(%%): (% style="color: #BA2121;" %)"JSON-RPC-2.0/UFO-RPC-6"(%%),
539 + (% style="font-weight: bold; color: #008000;" %)"contentType"(%%): (% style="color: #BA2121;" %)"application/json"(%%),
540 + (% style="font-weight: bold; color: #008000;" %)"description"(%%): (% style="color: #BA2121;" %)""(%%),
541 + (% style="font-weight: bold; color: #008000;" %)"transport"(%%): {
542 + (% style="font-weight: bold; color: #008000;" %)"sync"(%%): {
543 + (% style="font-weight: bold; color: #008000;" %)"scheme"(%%): (% style="color: #BA2121;" %)"http"(%%),
544 + (% style="font-weight: bold; color: #008000;" %)"host"(%%): (% style="color: #BA2121;" %)"example.com"(%%),
545 + (% style="font-weight: bold; color: #008000;" %)"path"(%%): (% style="color: #BA2121;" %)"/api"(%%),
546 + (% style="font-weight: bold; color: #008000;" %)"method"(%%): (% style="color: #BA2121;" %)"POST"(%%)
237 237   },
238 - "async": {
239 - "scheme": "amqp",
240 - "user": "{user}",
241 - "pass": "{pass}",
242 - "host": "async_rabbit",
243 - "port": 5672,
244 - "path": "/%2f/json-rpc"
548 + (% style="font-weight: bold; color: #008000;" %)"async"(%%): {
549 + (% style="font-weight: bold; color: #008000;" %)"scheme"(%%): (% style="color: #BA2121;" %)"amqp"(%%),
550 + (% style="font-weight: bold; color: #008000;" %)"user"(%%): (% style="color: #BA2121;" %)"{user}"(%%),
551 + (% style="font-weight: bold; color: #008000;" %)"pass"(%%): (% style="color: #BA2121;" %)"{pass}"(%%),
552 + (% style="font-weight: bold; color: #008000;" %)"host"(%%): (% style="color: #BA2121;" %)"async_rabbit"(%%),
553 + (% style="font-weight: bold; color: #008000;" %)"port"(%%): (% style="color: #666666;" %)5672(%%),
554 + (% style="font-weight: bold; color: #008000;" %)"path"(%%): (% style="color: #BA2121;" %)"/%2f/json-rpc"(%%)
245 245   }
246 246   },
247 - "methods": {
248 - ...
557 + (% style="font-weight: bold; color: #008000;" %)"methods"(%%): {
558 + (% style="border: 1px solid #FF0000;" %)...(%%)
249 249   }
250 250  }
251 -{{/code}}
561 +)))
562 +)))
563 +)))
564 +)))
252 252  
253 -{{info}}
566 +(% class="box infomessage" %)
567 +(((
254 254  Не переймайтеся щодо безпеки ваших авторизаційних даних. що містяться в DSN.
255 255  
256 256  Документатор побудований таким чином, що перед виводом інформації про DSN він видаляє дані про користувача і його пароль, а також інші секретні дані, як то токени, секретні ключі, тощо.
257 257  
258 -Шаблон, по якому відбувається захист {{code language="none"}}/([\w\d_]*(?:secret|access|token|key)[_\w]*)=((?:\w|\d)+(?=&?))/{{/code}}.
572 +Шаблон, по якому відбувається захист (% class="box code" %)/([\w\d_]*(?:secret|access|token|key)[_\w]*)=((?:\w|\d)+(?=&?))/(%%).
259 259  
260 260  Приклад:
261 261  
262 -{{code language="json" layout="LINENUMBERS" title="RPC_TRANSPORT_DSN=https://sqs.eu-west-3.amazonaws.com/123456789012/messages?access_key=AKIAIOSFODNN7EXAMPLE&secret_key=j17M97ffSVoKI0briFoo9a"}}
576 +(% class="box" %)
577 +(((
578 +RPC_TRANSPORT_DSN=https://sqs.eu-west-3.amazonaws.com/123456789012/messages?access_key=AKIAIOSFODNN7EXAMPLE&secret_key=j17M97ffSVoKI0briFoo9a
579 +
580 +(% class="code" %)
581 +(((
582 +(% class="linenoswrapper" %)
583 +(((
584 +(% class="linenos" %)
585 +(((
586 +1
587 +2
588 +3
589 +4
590 +5
591 +6
592 +7
593 +8\\
594 +)))
595 +
596 +(((
263 263  {
264 - "async": {
265 - "scheme": "https",
266 - "host": "sqs.eu-west-3.amazonaws.com",
267 - "path": "/123456789012/messages",
268 - "query": "access_key={access_key}&secret_key={secret_key}"
598 + (% style="font-weight: bold; color: #008000;" %)"async"(%%): {
599 + (% style="font-weight: bold; color: #008000;" %)"scheme"(%%): (% style="color: #BA2121;" %)"https"(%%),
600 + (% style="font-weight: bold; color: #008000;" %)"host"(%%): (% style="color: #BA2121;" %)"sqs.eu-west-3.amazonaws.com"(%%),
601 + (% style="font-weight: bold; color: #008000;" %)"path"(%%): (% style="color: #BA2121;" %)"/123456789012/messages"(%%),
602 + (% style="font-weight: bold; color: #008000;" %)"query"(%%): (% style="color: #BA2121;" %)"access_key={access_key}&secret_key={secret_key}"(%%)
269 269   }
270 270  }
271 -{{/code}}
272 -{{/info}}
605 +)))
606 +)))
607 +)))
608 +)))
609 +)))
273 273  
274 -=== Параметр {{code language="none"}}validations{{/code}} ===
611 +=== Параметр (% class="box code" %)validations(%%) ===
275 275  
276 276  Відповідає за відображення в документації методів додаткових блоків, що вказують на вимоги до валідації даних.
277 277  
278 278  Наразі цей блок має два можливих налаштування:
279 279  
280 -* {{code language="none"}}json_schema: <bool>{{/code}}
281 -* {{code language="none"}}symfony_asserts: <bool>{{/code}}
617 +* (% class="box code" %)json_schema: <bool>
618 +* (% class="box code" %)symfony_asserts: <bool>
282 282  
283 -У всіх опцій в цьому параметрі значення за замовченням {{code language="none"}}false{{/code}}, тобто ці блоки не будуть відображатися в документації.
284 -Якщо ви потребуєте якийсь з цих блоків інформації при запиті документації, то встановіть значення в {{code language="none"}}true{{/code}}.
620 +У всіх опцій в цьому параметрі значення за замовченням (% class="box code" %)false(%%), тобто ці блоки не будуть відображатися в документації.
621 +Якщо ви потребуєте якийсь з цих блоків інформації при запиті документації, то встановіть значення в (% class="box code" %)true(%%).
285 285  
286 -{{code language="yaml" layout="LINENUMBERS" title="config/packages/ufo_json_rpc.yaml"}}
287 -ufo_json_rpc:
288 - docs:
289 - json_schema: true
290 - symfony_asserts: true
291 -{{/code}}
623 +(% class="box" %)
624 +(((
625 +config/packages/ufo_json_rpc.yaml
292 292  
627 +(% class="code" %)
628 +(((
629 +(% class="linenoswrapper" %)
630 +(((
631 +(% class="linenos" %)
632 +(((
633 +1
634 +2
635 +3
636 +4\\
637 +)))
638 +
639 +(((
640 +(% style="font-weight: bold; color: #008000;" %)ufo_json_rpc(%%):
641 + (% style="font-weight: bold; color: #008000;" %)docs(%%):
642 + (% style="font-weight: bold; color: #008000;" %)json_schema(%%): true
643 + (% style="font-weight: bold; color: #008000;" %)symfony_asserts(%%): true
644 +)))
645 +)))
646 +)))
647 +)))
648 +
293 293  ==== **Приклад документації ** ====
294 294  
295 295  (% class="box infomessage" %)
296 296  (((
297 297  В цьому прикладі я видалив вміст обʼєктів symfony_assertions для спрощення прикладу.
298 -Детальніше про валідацію методів дивись сторінку **[[Валідація процедур>>doc:.add_rpc_service.assertions.WebHome]]**
654 +Детальніше про валідацію методів дивись сторінку **[[path:/bin/view/docs/JsonRpcBundle/add_rpc_service/assertions/]]**
299 299  )))
300 300  
301 -{{code language="json" layout="LINENUMBERS" title="GET: /api"}}
657 +(% class="box" %)
658 +(((
659 +GET: /api
660 +
661 +(% class="code" %)
662 +(((
663 +(% class="linenoswrapper" %)
664 +(((
665 +(% class="linenos" %)
666 +(((
667 +1
668 +2
669 +3
670 +4
671 +5
672 +6
673 +7
674 +8
675 +9
676 +10
677 +11
678 +12
679 +13
680 +14
681 +15
682 +16
683 +17
684 +18
685 +19
686 +20
687 +21
688 +22
689 +23
690 +24
691 +25
692 +26
693 +27
694 +28
695 +29
696 +30
697 +31
698 +32
699 +33
700 +34
701 +35
702 +36
703 +37
704 +38
705 +39
706 +40
707 +41
708 +42
709 +43
710 +44
711 +45
712 +46
713 +47
714 +48
715 +49
716 +50
717 +51
718 +52
719 +53
720 +54
721 +55
722 +56
723 +57
724 +58
725 +59
726 +60
727 +61
728 +62
729 +63
730 +64
731 +65
732 +66
733 +67
734 +68
735 +69
736 +70
737 +71
738 +72
739 +73
740 +74
741 +75
742 +76
743 +77
744 +78
745 +79
746 +80
747 +81
748 +82
749 +83
750 +84
751 +85
752 +86
753 +87
754 +88
755 +89
756 +90
757 +91
758 +92
759 +93
760 +94
761 +95
762 +96
763 +97
764 +98
765 +99
766 +100
767 +101
768 +102
769 +103
770 +104
771 +105
772 +106
773 +107
774 +108
775 +109
776 +110
777 +111
778 +112
779 +113
780 +114
781 +115
782 +116
783 +117
784 +118
785 +119
786 +120
787 +121
788 +122
789 +123
790 +124
791 +125
792 +126
793 +127\\
794 +)))
795 +
796 +(((
302 302  {
303 - "envelope": "JSON-RPC-2.0/UFO-RPC-6",
304 - "contentType": "application/json",
305 - "description": "",
306 - "transport": {
307 - "sync": {
308 - "scheme": "https",
309 - "host": "example.com",
310 - "path": "/api",
311 - "method": "POST"
798 + (% style="font-weight: bold; color: #008000;" %)"envelope"(%%): (% style="color: #BA2121;" %)"JSON-RPC-2.0/UFO-RPC-6"(%%),
799 + (% style="font-weight: bold; color: #008000;" %)"contentType"(%%): (% style="color: #BA2121;" %)"application/json"(%%),
800 + (% style="font-weight: bold; color: #008000;" %)"description"(%%): (% style="color: #BA2121;" %)""(%%),
801 + (% style="font-weight: bold; color: #008000;" %)"transport"(%%): {
802 + (% style="font-weight: bold; color: #008000;" %)"sync"(%%): {
803 + (% style="font-weight: bold; color: #008000;" %)"scheme"(%%): (% style="color: #BA2121;" %)"https"(%%),
804 + (% style="font-weight: bold; color: #008000;" %)"host"(%%): (% style="color: #BA2121;" %)"example.com"(%%),
805 + (% style="font-weight: bold; color: #008000;" %)"path"(%%): (% style="color: #BA2121;" %)"/api"(%%),
806 + (% style="font-weight: bold; color: #008000;" %)"method"(%%): (% style="color: #BA2121;" %)"POST"(%%)
312 312   }
313 313   },
314 - "methods": {
315 - "getUserNameByUuid": {
316 - "name": "getUserNameByUuid",
317 - "description": "Get username by id",
318 - "parameters": {
319 - "userId": {
320 - "type": "string",
321 - "name": "userId",
322 - "description": "User id in uuid format",
323 - "optional": false
809 + (% style="font-weight: bold; color: #008000;" %)"methods"(%%): {
810 + (% style="font-weight: bold; color: #008000;" %)"getUserNameByUuid"(%%): {
811 + (% style="font-weight: bold; color: #008000;" %)"name"(%%): (% style="color: #BA2121;" %)"getUserNameByUuid"(%%),
812 + (% style="font-weight: bold; color: #008000;" %)"description"(%%): (% style="color: #BA2121;" %)"Get username by id"(%%),
813 + (% style="font-weight: bold; color: #008000;" %)"parameters"(%%): {
814 + (% style="font-weight: bold; color: #008000;" %)"userId"(%%): {
815 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"string"(%%),
816 + (% style="font-weight: bold; color: #008000;" %)"name"(%%): (% style="color: #BA2121;" %)"userId"(%%),
817 + (% style="font-weight: bold; color: #008000;" %)"description"(%%): (% style="color: #BA2121;" %)"User id in uuid format"(%%),
818 + (% style="font-weight: bold; color: #008000;" %)"optional"(%%): (% style="font-weight: bold; color: #008000;" %)false(%%)
324 324   }
325 325   },
326 - "returns": "string",
327 - "responseFormat": "string",
328 - "json_schema": {
329 - "$schema": "http://json-schema.org/draft-07/schema#",
330 - "type": "object",
331 - "properties": {
332 - "userId": {
333 - "type": "string"
821 + (% style="font-weight: bold; color: #008000;" %)"returns"(%%): (% style="color: #BA2121;" %)"string"(%%),
822 + (% style="font-weight: bold; color: #008000;" %)"responseFormat"(%%): (% style="color: #BA2121;" %)"string"(%%),
823 + (% style="font-weight: bold; color: #008000;" %)"json_schema"(%%): {
824 + (% style="font-weight: bold; color: #008000;" %)"$schema"(%%): (% style="color: #BA2121;" %)"http:~/~/json-schema.org/draft-07/schema#"(%%),
825 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"object"(%%),
826 + (% style="font-weight: bold; color: #008000;" %)"properties"(%%): {
827 + (% style="font-weight: bold; color: #008000;" %)"userId"(%%): {
828 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"string"(%%)
334 334   }
335 335   },
336 - "required": [
337 - "userId"
831 + (% style="font-weight: bold; color: #008000;" %)"required"(%%): [
832 + (% style="color: #BA2121;" %)"userId"(%%)
338 338   ]
339 339   },
340 - "symfony_assertions": {
341 - "userId": [
835 + (% style="font-weight: bold; color: #008000;" %)"symfony_assertions"(%%): {
836 + (% style="font-weight: bold; color: #008000;" %)"userId"(%%): [
342 342   {
343 - "class": "Symfony\\Component\\Validator\\Constraints\\Uuid",
344 - "context": {}
838 + (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\Uuid"(%%),
839 + (% style="font-weight: bold; color: #008000;" %)"context"(%%): {}
345 345   }
346 346   ]
347 347   }
348 348   },
349 - "sendEmail": {
350 - "name": "sendEmail",
351 - "description": "Send mail",
352 - "parameters": {
353 - "email": {
354 - "type": "string",
355 - "name": "email",
356 - "description": "",
357 - "optional": false
844 + (% style="font-weight: bold; color: #008000;" %)"sendEmail"(%%): {
845 + (% style="font-weight: bold; color: #008000;" %)"name"(%%): (% style="color: #BA2121;" %)"sendEmail"(%%),
846 + (% style="font-weight: bold; color: #008000;" %)"description"(%%): (% style="color: #BA2121;" %)"Send mail"(%%),
847 + (% style="font-weight: bold; color: #008000;" %)"parameters"(%%): {
848 + (% style="font-weight: bold; color: #008000;" %)"email"(%%): {
849 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"string"(%%),
850 + (% style="font-weight: bold; color: #008000;" %)"name"(%%): (% style="color: #BA2121;" %)"email"(%%),
851 + (% style="font-weight: bold; color: #008000;" %)"description"(%%): (% style="color: #BA2121;" %)""(%%),
852 + (% style="font-weight: bold; color: #008000;" %)"optional"(%%): (% style="font-weight: bold; color: #008000;" %)false(%%)
358 358   },
359 - "subject": {
360 - "type": "string",
361 - "name": "subject",
362 - "description": "",
363 - "optional": false
854 + (% style="font-weight: bold; color: #008000;" %)"subject"(%%): {
855 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"string"(%%),
856 + (% style="font-weight: bold; color: #008000;" %)"name"(%%): (% style="color: #BA2121;" %)"subject"(%%),
857 + (% style="font-weight: bold; color: #008000;" %)"description"(%%): (% style="color: #BA2121;" %)""(%%),
858 + (% style="font-weight: bold; color: #008000;" %)"optional"(%%): (% style="font-weight: bold; color: #008000;" %)false(%%)
364 364   },
365 - "text": {
366 - "type": "string",
367 - "name": "text",
368 - "description": "",
369 - "optional": false
860 + (% style="font-weight: bold; color: #008000;" %)"text"(%%): {
861 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"string"(%%),
862 + (% style="font-weight: bold; color: #008000;" %)"name"(%%): (% style="color: #BA2121;" %)"text"(%%),
863 + (% style="font-weight: bold; color: #008000;" %)"description"(%%): (% style="color: #BA2121;" %)""(%%),
864 + (% style="font-weight: bold; color: #008000;" %)"optional"(%%): (% style="font-weight: bold; color: #008000;" %)false(%%)
370 370   }
371 371   },
372 - "returns": "boolean",
373 - "responseFormat": "boolean",
374 - "json_schema": {
375 - "$schema": "http://json-schema.org/draft-07/schema#",
376 - "type": "object",
377 - "properties": {
378 - "email": {
379 - "type": "string",
380 - "format": "email"
867 + (% style="font-weight: bold; color: #008000;" %)"returns"(%%): (% style="color: #BA2121;" %)"boolean"(%%),
868 + (% style="font-weight: bold; color: #008000;" %)"responseFormat"(%%): (% style="color: #BA2121;" %)"boolean"(%%),
869 + (% style="font-weight: bold; color: #008000;" %)"json_schema"(%%): {
870 + (% style="font-weight: bold; color: #008000;" %)"$schema"(%%): (% style="color: #BA2121;" %)"http:~/~/json-schema.org/draft-07/schema#"(%%),
871 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"object"(%%),
872 + (% style="font-weight: bold; color: #008000;" %)"properties"(%%): {
873 + (% style="font-weight: bold; color: #008000;" %)"email"(%%): {
874 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"string"(%%),
875 + (% style="font-weight: bold; color: #008000;" %)"format"(%%): (% style="color: #BA2121;" %)"email"(%%)
381 381   },
382 - "subject": {
383 - "type": "string",
384 - "minLength": 1,
385 - "maxLength": 100
877 + (% style="font-weight: bold; color: #008000;" %)"subject"(%%): {
878 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"string"(%%),
879 + (% style="font-weight: bold; color: #008000;" %)"minLength"(%%): (% style="color: #666666;" %)1(%%),
880 + (% style="font-weight: bold; color: #008000;" %)"maxLength"(%%): (% style="color: #666666;" %)100(%%)
386 386   },
387 - "text": {
388 - "type": "string",
389 - "minLength": 10
882 + (% style="font-weight: bold; color: #008000;" %)"text"(%%): {
883 + (% style="font-weight: bold; color: #008000;" %)"type"(%%): (% style="color: #BA2121;" %)"string"(%%),
884 + (% style="font-weight: bold; color: #008000;" %)"minLength"(%%): (% style="color: #666666;" %)10(%%)
390 390   }
391 391   },
392 - "required": [
393 - "email",
394 - "subject",
395 - "text"
887 + (% style="font-weight: bold; color: #008000;" %)"required"(%%): [
888 + (% style="color: #BA2121;" %)"email"(%%),
889 + (% style="color: #BA2121;" %)"subject"(%%),
890 + (% style="color: #BA2121;" %)"text"(%%)
396 396   ]
397 397   },
398 - "symfony_assertions": {
399 - "email": [
893 + (% style="font-weight: bold; color: #008000;" %)"symfony_assertions"(%%): {
894 + (% style="font-weight: bold; color: #008000;" %)"email"(%%): [
400 400   {
401 - "class": "Symfony\\Component\\Validator\\Constraints\\Email",
402 - "context": {}
896 + (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\Email"(%%),
897 + (% style="font-weight: bold; color: #008000;" %)"context"(%%): {}
403 403   }
404 404   ],
405 - "subject": [
900 + (% style="font-weight: bold; color: #008000;" %)"subject"(%%): [
406 406   {
407 - "class": "Symfony\\Component\\Validator\\Constraints\\NotBlank",
408 - "context": {}
902 + (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\NotBlank"(%%),
903 + (% style="font-weight: bold; color: #008000;" %)"context"(%%): {}
409 409   },
410 410   {
411 - "class": "Symfony\\Component\\Validator\\Constraints\\Length",
412 - "context": {}
906 + (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\Length"(%%),
907 + (% style="font-weight: bold; color: #008000;" %)"context"(%%): {}
413 413   }
414 414   ],
415 - "text": [
910 + (% style="font-weight: bold; color: #008000;" %)"text"(%%): [
416 416   {
417 - "class": "Symfony\\Component\\Validator\\Constraints\\NotBlank",
418 - "context": {}
912 + (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\NotBlank"(%%),
913 + (% style="font-weight: bold; color: #008000;" %)"context"(%%): {}
419 419   },
420 420   {
421 - "class": "Symfony\\Component\\Validator\\Constraints\\Length",
422 - "context": {}
916 + (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\Length"(%%),
917 + (% style="font-weight: bold; color: #008000;" %)"context"(%%): {}
423 423   }
424 424   ]
425 425   }
... ... @@ -426,4 +426,7 @@
426 426   }
427 427   }
428 428  }
429 -{{/code}}
924 +)))
925 +)))
926 +)))
927 +)))