Вікі-код для 2. Налаштування бандлу
Показати останніх авторів
| author | version | line-number | content |
|---|---|---|---|
| 1 | (% class="box floatinginfobox" %) | ||
| 2 | ((( | ||
| 3 | **Зміст** | ||
| 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 | |||
| 24 | (% class="wikigeneratedid" %) | ||
| 25 | Всі налаштування бандла знаходяться в файлі (% class="box code" %)config/packages/ufo_json_rpc.yaml(%%). | ||
| 26 | |||
| 27 | (% class="wikigeneratedid" %) | ||
| 28 | Є можливість налаштувати параметри захисту API та деякі параметри формату даних, що віддається при запиті документації. | ||
| 29 | |||
| 30 | = Блок (% class="box code" %)security(%%) = | ||
| 31 | |||
| 32 | Наразі єдиним механізмом захисту доступу до вашого API є встановлення перевірки ключа доступу (api_token). | ||
| 33 | |||
| 34 | == Параметр (% class="box code" %)protected_methods(%%) == | ||
| 35 | |||
| 36 | (% class="wikigeneratedid" %) | ||
| 37 | Цей параметр приймає масив назв http методів, які мають бути захищені. | ||
| 38 | |||
| 39 | (% class="wikigeneratedid" %) | ||
| 40 | За замовченням ввімкнут захист лише для методу POST. Ви можете: | ||
| 41 | |||
| 42 | * вказати пустий масив (% class="box code" %)[](%%) щоб зробити API повністю відкритим | ||
| 43 | |||
| 44 | (% class="box" %) | ||
| 45 | ((( | ||
| 46 | config/packages/ufo_json_rpc.yaml | ||
| 47 | |||
| 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 | |||
| 68 | * вказати додатково захист для методу GET, що зробить запит документації недоступним без токену в заголовках запиту | ||
| 69 | |||
| 70 | (% class="box" %) | ||
| 71 | ((( | ||
| 72 | config/packages/ufo_json_rpc.yaml | ||
| 73 | |||
| 74 | (% class="code" %) | ||
| 75 | ((( | ||
| 76 | (% class="linenoswrapper" %) | ||
| 77 | ((( | ||
| 78 | (% class="linenos" %) | ||
| 79 | ((( | ||
| 80 | 1 | ||
| 81 | 2 | ||
| 82 | 3\\ | ||
| 83 | ))) | ||
| 84 | |||
| 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 | |||
| 96 | Перш за все, треба визначитися з назвою токену. | ||
| 97 | |||
| 98 | == Параметр (% class="box code" %)token_key_in_header(%%) == | ||
| 99 | |||
| 100 | Компонент (% class="box code" %)RpcSecurity(%%) буде шукати в заголовках запиту специфічний ключ, який ви можете встановити в налаштуваннях пакету, значення за замовченням (% class="box code" %)token_key_in_header: 'Ufo-RPC-Token'(%%), ви можете встановити будь-яке інше значення яке відповідає наступним вимогам. | ||
| 101 | |||
| 102 | \\ | ||
| 103 | |||
| 104 | (% class="spoiler" %) | ||
| 105 | ((( | ||
| 106 | (% class="spoilerTitle" %) | ||
| 107 | ((( | ||
| 108 | Вимоги до формування заголовків протоколу HTTP | ||
| 109 | ))) | ||
| 110 | |||
| 111 | (% class="spoilerContent hidden" %) | ||
| 112 | ((( | ||
| 113 | Вимоги до назв заголовків HTTP не є строго регульованими щодо капіталізації, оскільки HTTP заголовки нечутливі до регістру. Однак, існують деякі загальні практики і стандарти, які зазвичай дотримуються для кращої читабельності та узгодженості: | ||
| 114 | |||
| 115 | - Капіталізація: Зазвичай назви HTTP заголовків пишуться з використанням CamelCase, де кожне слово починається з великої літери, наприклад, Content-Type, User-Agent, Accept-Encoding. Це не впливає на технічну обробку заголовків, але робить їх легше читати. | ||
| 116 | - Унікальність: Кожен заголовок повинен мати унікальну назву у контексті одного HTTP запиту або відповіді. Не можна використовувати однакові назви для різних заголовків у тому самому запиті чи відповіді. | ||
| 117 | - Спеціальні заголовки: Існують заголовки, які використовуються специфічно для контролю поведінки кешування (Cache-Control), безпеки (Strict-Transport-Security), аутентифікації (Authorization), тощо. | ||
| 118 | - Норми RFC: Вимоги до заголовків регулюються документами RFC, які визначають стандарти для протоколів Інтернету. Наприклад, загальні заголовки і їхнє використання описані в RFC 7231. | ||
| 119 | ))) | ||
| 120 | ))) | ||
| 121 | |||
| 122 | |||
| 123 | |||
| 124 | |||
| 125 | |||
| 126 | == Параметр (% class="box code" %)clients_tokens(%%) == | ||
| 127 | |||
| 128 | Тепер слід вказати масив клієнтськіх токенів, які будуть мати доступ до API. | ||
| 129 | |||
| 130 | Тут є певна варіативність. | ||
| 131 | |||
| 132 | === Токени в параметрах === | ||
| 133 | |||
| 134 | (% class="box errormessage" %) | ||
| 135 | ((( | ||
| 136 | **НЕ РЕКОМЕНДОВАНО!!!** | ||
| 137 | \\Цей підхід допускається лише для локального тестування API | ||
| 138 | ))) | ||
| 139 | |||
| 140 | Є можливість прописати токени хардкодом прямо в файлі налаштувань. | ||
| 141 | |||
| 142 | Це погано з позиції безпеки, якщо код зберігається в публічному репозиторію, то до цього токену буде мати доступ кожен. | ||
| 143 | |||
| 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!(%%) | ||
| 170 | |||
| 171 | ))) | ||
| 172 | ))) | ||
| 173 | ))) | ||
| 174 | ))) | ||
| 175 | |||
| 176 | === Токени в змінних оточення === | ||
| 177 | |||
| 178 | Це найбільш доцільний механізм у разі, якщо ви розробляєте сервіс для розподіленого бекенду, що написаний на SOA (Сервіс-Орієнтована Архітектура). Зазвичай, в такому випадку, вам треба відкрити доступ до апі одному або обмеженій кількості клієнтських додатків і оновлення ключів не буде відбуватися занадто часто. | ||
| 179 | |||
| 180 | В такому випадку можна прописати токени в змінних оточення (файл (% class="box code" %).env.local(%%) під час локальної розробки). Цей механізм достатньо безпечний з боку збереження доступів. | ||
| 181 | |||
| 182 | ((( | ||
| 183 | (% class="box" %) | ||
| 184 | ((( | ||
| 185 | .env.local | ||
| 186 | |||
| 187 | (% class="code" %) | ||
| 188 | ((( | ||
| 189 | (% class="linenoswrapper" %) | ||
| 190 | ((( | ||
| 191 | (% class="linenos" %) | ||
| 192 | ((( | ||
| 193 | 1 | ||
| 194 | 2\\ | ||
| 195 | ))) | ||
| 196 | |||
| 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 | |||
| 238 | === Токени для користувача === | ||
| 239 | |||
| 240 | Припускаю, що у вас може виникнути потреба зробити персональні ключі для користувачів вашого додатку, можливо ви захочете впровадити ліміти або інші обмеження. | ||
| 241 | В такому випадку вам не потрібно вказувати перелік токенів в конфігах, ви можете зберігати їх в базі даних або іншому місці згідно вашій бізнес-логіки. Єдина вимога, у вас має бути сервіс, який вміє перевіряти чи існує наданий токен. | ||
| 242 | |||
| 243 | Для того, щоб JsonRpcServer міг використовувати вашу логіку, доведеться реалізувати власний клас, що реалізує інтерфейс (% class="box code" %)Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator | ||
| 244 | |||
| 245 | (% class="box" %) | ||
| 246 | ((( | ||
| 247 | ==== Приклад власного валідатора токенів ==== | ||
| 248 | |||
| 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 | ))) | ||
| 280 | |||
| 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 | ||
| 289 | { | ||
| 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(%%) | ||
| 292 | { | ||
| 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(%%)); | ||
| 298 | } | ||
| 299 | } | ||
| 300 | } | ||
| 301 | ))) | ||
| 302 | ))) | ||
| 303 | ))) | ||
| 304 | ))) | ||
| 305 | |||
| 306 | (% class="box warningmessage" %) | ||
| 307 | ((( | ||
| 308 | **ВАЖЛИВО!!!** | ||
| 309 | Метод (% class="box code" %)isValid(%%) має повертати (% class="box code" %)true(%%) якщо токен існує і валідний, або викидати (% class="box code" %)Ufo\RpcError\RpcInvalidTokenException(%%) в іншому разі. | ||
| 310 | ))) | ||
| 311 | |||
| 312 | Після цього вам потрібно в файлі (% class="box code" %)config/services.yaml(%%) прописати що класи, що мають залежність від інтерфейса (% class="box code" %)ITokenValidator(%%) мають приймати ваш новий клас. | ||
| 313 | |||
| 314 | (% class="box" %) | ||
| 315 | ((( | ||
| 316 | config/services.yaml | ||
| 317 | |||
| 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 | ))) | ||
| 335 | |||
| 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 | ))) | ||
| 349 | |||
| 350 | = Блок (% class="box code" %)async(%%) = | ||
| 351 | |||
| 352 | Цей блок для налаштування [[асинхронного транспорту>>path:/bin/view/docs/JsonRpcBundle/functionality/async/]]. | ||
| 353 | |||
| 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]]. | ||
| 355 | |||
| 356 | (% class="box" %) | ||
| 357 | ((( | ||
| 358 | config/packages/ufo_json_rpc.yaml | ||
| 359 | |||
| 360 | (% class="code" %) | ||
| 361 | ((( | ||
| 362 | (% class="linenoswrapper" %) | ||
| 363 | ((( | ||
| 364 | (% class="linenos" %) | ||
| 365 | ((( | ||
| 366 | 1 | ||
| 367 | 2 | ||
| 368 | 3 | ||
| 369 | 4\\ | ||
| 370 | ))) | ||
| 371 | |||
| 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 | |||
| 381 | (% class="box warningmessage" %) | ||
| 382 | ((( | ||
| 383 | Це налаштування має на увазі, що у вас в змінних оточення встановлена змінна RPC_TRANSPORT_DSN що містить DSN рядок. | ||
| 384 | ))) | ||
| 385 | |||
| 386 | = Блок (% class="box code" %)docs(%%) = | ||
| 387 | |||
| 388 | Це блок який налаштовує генерацію документації коли ви робите GET запит на RPC Server | ||
| 389 | |||
| 390 | == Секція (% class="box code" %)response(%%) == | ||
| 391 | |||
| 392 | Містить налаштування, що відповідають за вміст відповіді. | ||
| 393 | |||
| 394 | === Параметр (% class="box code" %)key_for_methods(%%) === | ||
| 395 | |||
| 396 | Цей параметр дозволяє вказати назву ключа у відповіді в якій буде віддаватися масив доступних сервісів. | ||
| 397 | |||
| 398 | Значення за замовченням (% class="box code" %)methods(%%). Може мати будь-яке значення типу рядок. | ||
| 399 | |||
| 400 | (% class="box" %) | ||
| 401 | ((( | ||
| 402 | config/packages/ufo_json_rpc.yaml | ||
| 403 | |||
| 404 | (% class="code" %) | ||
| 405 | ((( | ||
| 406 | (% class="linenoswrapper" %) | ||
| 407 | ((( | ||
| 408 | (% class="linenos" %) | ||
| 409 | ((( | ||
| 410 | 1 | ||
| 411 | 2 | ||
| 412 | 3\\ | ||
| 413 | ))) | ||
| 414 | |||
| 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 | ))) | ||
| 423 | |||
| 424 | (% class="box" %) | ||
| 425 | ((( | ||
| 426 | config/packages/ufo_json_rpc.yaml | ||
| 427 | |||
| 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 | |||
| 474 | Відповідає за відображення в документації інформації про асинхронний транспорт. | ||
| 475 | |||
| 476 | (% class="box" %) | ||
| 477 | ((( | ||
| 478 | config/packages/ufo_json_rpc.yaml | ||
| 479 | |||
| 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 | |||
| 498 | ==== **Приклад документації ** ==== | ||
| 499 | |||
| 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 | ((( | ||
| 537 | { | ||
| 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"(%%) | ||
| 547 | }, | ||
| 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"(%%) | ||
| 555 | } | ||
| 556 | }, | ||
| 557 | (% style="font-weight: bold; color: #008000;" %)"methods"(%%): { | ||
| 558 | (% style="border: 1px solid #FF0000;" %)...(%%) | ||
| 559 | } | ||
| 560 | } | ||
| 561 | ))) | ||
| 562 | ))) | ||
| 563 | ))) | ||
| 564 | ))) | ||
| 565 | |||
| 566 | (% class="box infomessage" %) | ||
| 567 | ((( | ||
| 568 | Не переймайтеся щодо безпеки ваших авторизаційних даних. що містяться в DSN. | ||
| 569 | |||
| 570 | Документатор побудований таким чином, що перед виводом інформації про DSN він видаляє дані про користувача і його пароль, а також інші секретні дані, як то токени, секретні ключі, тощо. | ||
| 571 | |||
| 572 | Шаблон, по якому відбувається захист (% class="box code" %)/([\w\d_]*(?:secret|access|token|key)[_\w]*)=((?:\w|\d)+(?=&?))/(%%). | ||
| 573 | |||
| 574 | Приклад: | ||
| 575 | |||
| 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 | ((( | ||
| 597 | { | ||
| 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}"(%%) | ||
| 603 | } | ||
| 604 | } | ||
| 605 | ))) | ||
| 606 | ))) | ||
| 607 | ))) | ||
| 608 | ))) | ||
| 609 | ))) | ||
| 610 | |||
| 611 | === Параметр (% class="box code" %)validations(%%) === | ||
| 612 | |||
| 613 | Відповідає за відображення в документації методів додаткових блоків, що вказують на вимоги до валідації даних. | ||
| 614 | |||
| 615 | Наразі цей блок має два можливих налаштування: | ||
| 616 | |||
| 617 | * (% class="box code" %)json_schema: <bool> | ||
| 618 | * (% class="box code" %)symfony_asserts: <bool> | ||
| 619 | |||
| 620 | У всіх опцій в цьому параметрі значення за замовченням (% class="box code" %)false(%%), тобто ці блоки не будуть відображатися в документації. | ||
| 621 | Якщо ви потребуєте якийсь з цих блоків інформації при запиті документації, то встановіть значення в (% class="box code" %)true(%%). | ||
| 622 | |||
| 623 | (% class="box" %) | ||
| 624 | ((( | ||
| 625 | config/packages/ufo_json_rpc.yaml | ||
| 626 | |||
| 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 | |||
| 649 | ==== **Приклад документації ** ==== | ||
| 650 | |||
| 651 | (% class="box infomessage" %) | ||
| 652 | ((( | ||
| 653 | В цьому прикладі я видалив вміст обʼєктів symfony_assertions для спрощення прикладу. | ||
| 654 | Детальніше про валідацію методів дивись сторінку **[[path:/bin/view/docs/JsonRpcBundle/add_rpc_service/assertions/]]** | ||
| 655 | ))) | ||
| 656 | |||
| 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 | ((( | ||
| 797 | { | ||
| 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"(%%) | ||
| 807 | } | ||
| 808 | }, | ||
| 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(%%) | ||
| 819 | } | ||
| 820 | }, | ||
| 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"(%%) | ||
| 829 | } | ||
| 830 | }, | ||
| 831 | (% style="font-weight: bold; color: #008000;" %)"required"(%%): [ | ||
| 832 | (% style="color: #BA2121;" %)"userId"(%%) | ||
| 833 | ] | ||
| 834 | }, | ||
| 835 | (% style="font-weight: bold; color: #008000;" %)"symfony_assertions"(%%): { | ||
| 836 | (% style="font-weight: bold; color: #008000;" %)"userId"(%%): [ | ||
| 837 | { | ||
| 838 | (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\Uuid"(%%), | ||
| 839 | (% style="font-weight: bold; color: #008000;" %)"context"(%%): {} | ||
| 840 | } | ||
| 841 | ] | ||
| 842 | } | ||
| 843 | }, | ||
| 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(%%) | ||
| 853 | }, | ||
| 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(%%) | ||
| 859 | }, | ||
| 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(%%) | ||
| 865 | } | ||
| 866 | }, | ||
| 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"(%%) | ||
| 876 | }, | ||
| 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(%%) | ||
| 881 | }, | ||
| 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(%%) | ||
| 885 | } | ||
| 886 | }, | ||
| 887 | (% style="font-weight: bold; color: #008000;" %)"required"(%%): [ | ||
| 888 | (% style="color: #BA2121;" %)"email"(%%), | ||
| 889 | (% style="color: #BA2121;" %)"subject"(%%), | ||
| 890 | (% style="color: #BA2121;" %)"text"(%%) | ||
| 891 | ] | ||
| 892 | }, | ||
| 893 | (% style="font-weight: bold; color: #008000;" %)"symfony_assertions"(%%): { | ||
| 894 | (% style="font-weight: bold; color: #008000;" %)"email"(%%): [ | ||
| 895 | { | ||
| 896 | (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\Email"(%%), | ||
| 897 | (% style="font-weight: bold; color: #008000;" %)"context"(%%): {} | ||
| 898 | } | ||
| 899 | ], | ||
| 900 | (% style="font-weight: bold; color: #008000;" %)"subject"(%%): [ | ||
| 901 | { | ||
| 902 | (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\NotBlank"(%%), | ||
| 903 | (% style="font-weight: bold; color: #008000;" %)"context"(%%): {} | ||
| 904 | }, | ||
| 905 | { | ||
| 906 | (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\Length"(%%), | ||
| 907 | (% style="font-weight: bold; color: #008000;" %)"context"(%%): {} | ||
| 908 | } | ||
| 909 | ], | ||
| 910 | (% style="font-weight: bold; color: #008000;" %)"text"(%%): [ | ||
| 911 | { | ||
| 912 | (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\NotBlank"(%%), | ||
| 913 | (% style="font-weight: bold; color: #008000;" %)"context"(%%): {} | ||
| 914 | }, | ||
| 915 | { | ||
| 916 | (% style="font-weight: bold; color: #008000;" %)"class"(%%): (% style="color: #BA2121;" %)"Symfony~\~\Component~\~\Validator~\~\Constraints~\~\Length"(%%), | ||
| 917 | (% style="font-weight: bold; color: #008000;" %)"context"(%%): {} | ||
| 918 | } | ||
| 919 | ] | ||
| 920 | } | ||
| 921 | } | ||
| 922 | } | ||
| 923 | } | ||
| 924 | ))) | ||
| 925 | ))) | ||
| 926 | ))) | ||
| 927 | ))) |