Зміни в документі Версія 6: Налаштування
Остання зміна 2024/07/11 10:07 автором Ashterix
Підсумок
-
Властивості сторінки (1 змінено, 0 додано, 0 видалено)
Подробиці
- Властивості сторінки
-
- Вміст
-
... ... @@ -1,18 +1,37 @@ 1 - {{boxcssClass="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 -Всі налаштування бандла знаходяться в файлі {{codelanguage="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 -= Блок {{codelanguage="none"}}security{{/code}}=30 += Блок (% class="box code" %)security(%%) = 12 12 13 13 Наразі єдиним механізмом захисту доступу до вашого API є встановлення перевірки ключа доступу (api_token). 14 14 15 -== Параметр {{codelanguage="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 -* вказати пустий масив {{codelanguage="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 -== Параметр {{codelanguage="none"}}token_key_in_header{{/code}}==98 +== Параметр (% class="box code" %)token_key_in_header(%%) == 44 44 45 -Компонент {{codelanguage="none"}}RpcSecurity{{/code}}буде шукати в заголовках запиту специфічний ключ, який ви можете встановити в налаштуваннях пакету, значення за замовченням{{codelanguage="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 -В такому випадку можна прописати токени в змінних оточення (файл {{codelanguage="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 міг використовувати вашу логіку, доведеться реалізувати власний клас, що реалізує інтерфейс {{codelanguage="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 -Метод {{codelanguage="none"}}isValid{{/code}}має повертати{{codelanguage="none"}}true{{/code}}якщо токен існує і валідний, або викидати{{codelanguage="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 -Після цього вам потрібно в файлі {{codelanguage="none"}}config/services.yaml{{/code}}прописати що класи, що мають залежність від інтерфейса{{codelanguage="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 -= Блок {{codelanguage="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 -Додайте параметр {{codelanguage="none"}}rpc_async{{/code}}який містить рядок у форматі DSN. Цей рядок є конфігурацією [[Symfony Messenger>>https://symfony.com/doc/current/messenger.html]], він вказує на асинхронний транспорт по якому RPC Server буде очікувати вхідні запити якщо у вас запущений консюмер ({{codelanguage="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 -= Блок {{codelanguage="none"}}docs{{/code}}=386 += Блок (% class="box code" %)docs(%%) = 184 184 185 185 Це блок який налаштовує генерацію документації коли ви робите GET запит на RPC Server 186 186 187 -== Секція {{codelanguage="none"}}response{{/code}}==390 +== Секція (% class="box code" %)response(%%) == 188 188 189 189 Містить налаштування, що відповідають за вміст відповіді. 190 190 191 -=== Параметр {{codelanguage="none"}}key_for_methods{{/code}}===394 +=== Параметр (% class="box code" %)key_for_methods(%%) === 192 192 193 193 Цей параметр дозволяє вказати назву ключа у відповіді в якій буде віддаватися масив доступних сервісів. 194 194 195 -Значення за замовченням {{codelanguage="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 -Шаблон, по якому відбувається захист {{codelanguage="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 -=== Параметр {{codelanguage="none"}}validations{{/code}}===611 +=== Параметр (% class="box code" %)validations(%%) === 275 275 276 276 Відповідає за відображення в документації методів додаткових блоків, що вказують на вимоги до валідації даних. 277 277 278 278 Наразі цей блок має два можливих налаштування: 279 279 280 -* {{codelanguage="none"}}json_schema: <bool>{{/code}}281 -* {{codelanguage="none"}}symfony_asserts: <bool>{{/code}}617 +* (% class="box code" %)json_schema: <bool> 618 +* (% class="box code" %)symfony_asserts: <bool> 282 282 283 -У всіх опцій в цьому параметрі значення за замовченням {{codelanguage="none"}}false{{/code}}, тобто ці блоки не будуть відображатися в документації.284 -Якщо ви потребуєте якийсь з цих блоків інформації при запиті документації, то встановіть значення в {{codelanguage="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 +)))