Project

General

Profile

APIForNG » History » Version 45

Denis Kildishev, 03/24/2023 03:35 PM

1 1 Denis Kildishev
h1. APIForNG
2 4 Denis Kildishev
3 1 Denis Kildishev
По текущей модели предполагается использование следующих методов:
4 2 Denis Kildishev
Для всех методов по умолчанию используется один заголовочный параметр
5
Authorization со значением Bearer 36AC0A0F7F271314B72986EB54DB2343
6 1 Denis Kildishev
7 45 Denis Kildishev
1.Получение списка проектов (updated 1.4)
8 1 Denis Kildishev
Method:
9
GET
10
Path:
11
http://localhost:9988/projects
12 45 Denis Kildishev
Без дополнительных параметров.
13
Возвращает пары "имя хранимое: имя представления"
14
Пример "some-local-project:project". При этом первое используется для обращения к определенному проекту, в том числе при помощи API вызовов, а второе - для ссылок на артефакты проекта в других проектах. Например, так можно представить другой проек в котором будет ссылка вида project::Requirements.
15 2 Denis Kildishev
Пример выдачи
16 1 Denis Kildishev
<pre><code class="javascript">
17
{
18
  "success" : true,
19
  "result" : {
20 45 Denis Kildishev
    "projects" : [ "Example":"Example", "з1":"з1", "someos-arch":"arch", "somestpo":"stpo"],
21 10 Denis Kildishev
    "count" : 4
22 1 Denis Kildishev
  }
23
}
24 8 Alexey Khoroshilov
</code></pre>
25 1 Denis Kildishev
26 2 Denis Kildishev
2. Получение содержимого проекта(иерархия), для expandable - ограниченное 1м уровнем 
27 1 Denis Kildishev
Method:
28
GET
29
Path:
30 2 Denis Kildishev
http://localhost:9988/projects/{arch}[/expandable]
31
Здесь {arch} - имя проекта, на данный момент регистрозависимо
32
Без дополнительных параметров
33
Пример выдачи
34 9 Denis Kildishev
<pre><code class="javascript">
35 1 Denis Kildishev
{
36 9 Denis Kildishev
  "success": true,
37
  "result": {
38
    "name": "arch",
39
    "nodes": [
40
      {
41
        "uuid": "243f4afe-1d28-4652-80b9-4ad123b415a4"
42
        "name": "Documents",
43 32 Denis Kildishev
        "id": "Documents",
44 9 Denis Kildishev
        "type": "DocFolder",
45 1 Denis Kildishev
46 9 Denis Kildishev
      },
47
      {
48
        "uuid": "7a5374ee-eb7a-4731-997d-5f52f00ebc2e"
49
        "name": "Requirements",
50 32 Denis Kildishev
        "id": "Requirements",
51 9 Denis Kildishev
        "type": "Requirement",
52
        "haveChildren":"true",
53
        "children": [
54
          {
55
            "uuid": "8ccd86e3-5689-43aa-9241-04728447e8f7",
56
            "name": "001",
57 32 Denis Kildishev
            "id": "001",
58 9 Denis Kildishev
            "type": "Requirement",
59
            "children": [],
60
          }
61
        ]
62
      },
63
      {
64
        "uuid": "ff42a6f4-f9ac-48c3-b41c-c36395df8a85",
65
        "name": "Reports",
66 32 Denis Kildishev
        "id": "Reports",
67 9 Denis Kildishev
        "type": "ReportFolder"
68
      }
69
    ],
70 1 Denis Kildishev
  }
71 9 Denis Kildishev
}
72 1 Denis Kildishev
</code></pre>
73 32 Denis Kildishev
по умолчанию выдает все дерево с базовым набором из нескольких полей - уникального id uuid, идентефикатора id, являющегося фактически именем json представления на диске, отображаемого имени name, типа type и массива потомков children. 
74 1 Denis Kildishev
поле haveChildren присутствует если у узла есть потомки и работает даже когда children не видны в режиме expandable для 2 уровня вложенности
75
при режиме [expandable] потомки выдаются до 1 уровня вложенности
76 29 Denis Kildishev
В случае отсутствия проекта выдаст ошибку E1.
77 1 Denis Kildishev
78
3. Получение данных по поддереву
79
Method:
80
GET
81
Path:
82
http://localhost:9988/projects/{TEST}/hierarchy/ff42a6f4-f9ac-48c3-b41c-c36395df8a85[/expandable]
83
{TEST} - имя проекта
84
id после /hierarchy это id узла для которого получается поддерево, режим /expandable работает аналогично проекту
85
Без дополнительных параметров
86
Пример выдачи
87 9 Denis Kildishev
<pre><code class="javascript">
88 1 Denis Kildishev
{
89 9 Denis Kildishev
  "success": true, 
90
  "result": 
91
  {
92
    "uuid": "ff42a6f4-f9ac-48c3-b41c-c36395df8a85",
93 1 Denis Kildishev
    "name": "Reports",
94 32 Denis Kildishev
    "id": "Reports",
95 9 Denis Kildishev
    "type": "ReportFolder",
96
    "parent": "ff42a6f4-f9ac-48c3-b41c-c36395df8a85"
97
  }
98 1 Denis Kildishev
}
99
</code></pre>
100
Содержимое result аналогично описанию одного узла и всех его потомков[или потомков 1 уровня вложенности для expandable] в выдаче проекта
101 29 Denis Kildishev
В случае отсутствия проекта выдаст ошибку E1.
102
В случае отсутствия узла для которого выдается поддерева возвращает ошибку E2.
103 1 Denis Kildishev
104 45 Denis Kildishev
4. Получение свойств узлов (updated 1.4)
105 1 Denis Kildishev
Method:
106
POST
107
Path:
108
http://localhost:9988/projects/TEST/getattributes/
109
В теле запроса передаются все uuid ы узлов для которых нужно выдать свойства. Конкретная реализация пока уточняется, текущее предположение - просто передавать в текстовом виде с разделителем ;. Возможно будут передаваться в качестве массива по аналогии с передачей данных форм. Пример "4db0fbf4-f383-4740-9d72-891ef112f742;ff42a6f4-f9ac-48c3-b41c-c36395df8a85".
110
Пример выдачи
111 9 Denis Kildishev
<pre><code class="javascript">
112 1 Denis Kildishev
{
113 9 Denis Kildishev
  "success": true,
114
  "result": {
115 1 Denis Kildishev
    "attributes": {
116 9 Denis Kildishev
      "4db0fbf4-f383-4740-9d72-891ef112f742":{
117
        "Вид": {
118
          "value": "",
119 45 Denis Kildishev
          "rawValue": "",
120 1 Denis Kildishev
          "type": "STRING"
121 9 Denis Kildishev
        },
122
        "_index": {
123
          "value": "1",
124 45 Denis Kildishev
          "rawValue": "1",
125 1 Denis Kildishev
          "type": "STRING"
126 9 Denis Kildishev
        },
127
        "_name": {
128
          "value": "Хронология",
129 45 Denis Kildishev
          "rawValue": "Хронология",
130 1 Denis Kildishev
          "type": "STRING"
131 9 Denis Kildishev
        },
132
        "_type": {
133
          "value": "Requirement",
134 45 Denis Kildishev
          "rawValue": "Requirement",
135 1 Denis Kildishev
          "type": "STRING"
136 9 Denis Kildishev
        },
137
        "_id": {
138
          "value": "001",
139 45 Denis Kildishev
          "rawValue": "001",
140 1 Denis Kildishev
          "type": "STRING"
141 9 Denis Kildishev
        },
142
        "ForeignID": {
143
          "value": "1",
144 45 Denis Kildishev
          "rawValue": "1",
145 9 Denis Kildishev
          "type": "STRING"
146
        }
147
      },
148
      "9dffaddf-a55a-4fa1-a3bc-4a5fade4169f":{
149 1 Denis Kildishev
        "Вид": {
150 9 Denis Kildishev
          "value": "Заголовок",
151
          "enumName": "Вид",
152
          "valueType": "STRING",
153 45 Denis Kildishev
          "rawValue": "Заголовок",
154 1 Denis Kildishev
          "type": "ENUM"
155 9 Denis Kildishev
        },
156
        "_index": {
157
          "value": "1",
158 45 Denis Kildishev
          "rawValue": "1",
159 1 Denis Kildishev
          "type": "STRING"
160
        },
161 9 Denis Kildishev
        "_tags": {
162
          "value": [
163
            {
164 45 Denis Kildishev
              "value": "section_Архитектура_ПО_Поток_управления",
165
              "rawValue": "section_Архитектура_ПО"
166 9 Denis Kildishev
            }
167
          ],
168 1 Denis Kildishev
          "valuesType": "STRING",
169 9 Denis Kildishev
          "type": "LIST"
170
        },
171
        "_type": {
172
          "value": "Requirement",
173 45 Denis Kildishev
          "rawValue": "Requirement",
174 9 Denis Kildishev
          "type": "STRING"
175
        },
176
        "_id": {
177
          "value": "Поток управления",
178 45 Denis Kildishev
          "rawValue": "Поток управления",
179 9 Denis Kildishev
          "type": "STRING"
180
        },
181 1 Denis Kildishev
        "_description": {
182
          "value": " ",
183 45 Denis Kildishev
          "rawValue": " ",
184 1 Denis Kildishev
          "type": "HTML"
185
        },
186 45 Denis Kildishev
        "exampleNotLocal": {
187
          "value": " ",
188
          "rawValue": " ",
189
          "scope": "SUBTREE",
190
          "origin": "0b4f4643-fab6-48c6-b694-b8256fc79e0a",
191
          "type": "HTML"
192
        },
193
        "exampleLocal": {
194
          "value": " ",
195
          "rawValue": " ",
196
          "scope": "SUBTREE",
197
          "type": "HTML"
198
        },
199
        "exampleLocal2": {
200
          "value": " ",
201
          "rawValue": " ",
202
          "scope": "DIRECT_CHILDREN",
203
          "type": "HTML"
204
        },
205 9 Denis Kildishev
        "ForeignID": {
206
          "value": "2",
207 45 Denis Kildishev
          "rawValue": "2",
208 9 Denis Kildishev
          "type": "STRING"
209
        }
210
      }
211
    }
212 1 Denis Kildishev
  }
213
}
214
</code></pre>
215 9 Denis Kildishev
216 3 Denis Kildishev
В примере выдача свойств двух узлов. Они расположены в result в виде словаря где ключ это id а значение - набор свойств узла.
217 45 Denis Kildishev
Свойства включают rawValue - базовое значение свойство которое непосредственно редактируется в инструменте и value - результат подстановки выражений вида {val} позволяющих использовать значения других переменных в текущей.
218
Также может встречаться "scope" указывающий на область доступности текущего свойства. Большая часть свойств имеют scope равный LOCAL и их значения доступны только на текущем узле. При видимости DIRECT_CHILDREN свойство также доступно в потомках узла в котором оно было определено, а SUBTREE позволяет обеспечить доступность свойства во всем поддереве потомков.
219
Также стоит отметить origin указывающий на место определения свойства в ситуации когда оно было определено в другом узле. То есть, если в узле присутствует scope и origin одновременно - это означает что это свойство было определено в другом узле. Если есть только scope - это свойство определено в текущем узле но доступно и в его потомках.
220 3 Denis Kildishev
221
5. Метод для работы с ресурсами. Текущая реализация
222
Method:
223
GET
224
Path:
225
http://localhost:9988/projects/{TEST}/nodes/{n}/resources/{resFolder}/{res}
226
{Test} имя проекта
227
{n} - uuid узла
228
{resFolder} папка с ресурсами(внутри {node_id}_resources, например "images")
229 4 Denis Kildishev
{res} имя файла
230
Возвращает ответ типа APPLICATION_OCTET_STREAM включающий в себя содержимое нужного ресурса. В теле также передается имя файла.
231
Если ресурса нет то выдается ответ NOT_FOUND типа plain text
232
Если передано некорректное имя папки с ресурсами(включающее недопустимые символы) то выдается ответ INVALID FOLDER типа plain text
233
234 1 Denis Kildishev
Предположительно появится метод получения ресурсов по списку для множества узлов но потом
235
Возможный формат передачи данных - json пары
236 9 Denis Kildishev
<pre><code class="javascript">
237 1 Denis Kildishev
{"uuid":"resfolder/resname","uuid2":"resfolder2/resname2"}
238 9 Denis Kildishev
</code></pre>
239 1 Denis Kildishev
Возможный тип возвращаемого значения - multipart/mixed. Но при этом размер возвращаемых данных может оказаться значительным
240 11 Denis Kildishev
241
6. Метод для получения связей
242
Method:
243
POST
244
Path:
245
http://localhost:9988/projects/{TEST}/getlinks
246
В теле запроса передаются все uuid ы узлов для которых нужно выдать свойства. Текущее предположение - в текстовом виде с разделителем ';'. Пример "4db0fbf4-f383-4740-9d72-891ef112f742;ff42a6f4-f9ac-48c3-b41c-c36395df8a85".
247
Результат включает в себя аналог словаря uuid:{ссылки}. Если для узла ссылок нет то в выдачу он не попадает.
248
ссылки разбиты на 4 раздела
249
linkToRelations - исходящие ссылки по свойствам
250
linkedByRelations - входящие ссылки по свойствам
251
linkToTerms - связи от использования термина из другого узла к определению в данном узле
252
linkedByTerms - связи от использования термина из данного узла к определению в другом узле
253
Пример выдачи
254
<pre><code class="javascript">
255
{
256
  "success": true,
257
  "result": {
258
    "links": {
259
      "7a5374ee-eb7a-4731-997d-5f52f00ebc2e": {
260
        "linkToRelations": {
261
          "reg": [
262
            {
263
              "haveChildren": true,
264 1 Denis Kildishev
              "name": "Архитектура ПО",
265 32 Denis Kildishev
              "id": "Архитектура ПО",
266 11 Denis Kildishev
              "type": "Requirement",
267
              "parent": "7a5374ee-eb7a-4731-997d-5f52f00ebc2e",
268
              "externalId": "9",
269
              "uuid": "188f8992-12e1-4acc-bf5a-fd568b1a2161"
270
            }
271
          ],
272
        },
273
        "linkedByRelations": {
274
          "d": [
275
            {
276 1 Denis Kildishev
              "haveChildren": true,
277 32 Denis Kildishev
              "name": "если E = 2 k -1",
278 11 Denis Kildishev
              "id": "if01",
279
              "type": "Requirement",
280
              "project": "SQRT",
281
              "parent": "ba51211b-d1c6-46ae-9333-bdad409b1fdb",
282
              "uuid": "127bfded-ae30-4365-9274-c116201a4ac1"
283
            },
284 1 Denis Kildishev
            {
285 32 Denis Kildishev
              "name": "001",
286 11 Denis Kildishev
              "id": "001",
287
              "type": "Requirement",
288
              "project": "SQRT",
289
              "parent": "ebc37a22-15c5-482d-9e4c-8c23461fca39",
290
              "uuid": "57b80f94-9011-43d8-844f-5bef23e37afb"
291
            },
292 1 Denis Kildishev
            {
293 32 Denis Kildishev
              "name": "002",
294 11 Denis Kildishev
              "id": "002",
295
              "type": "Requirement",
296
              "project": "SQRT",
297
              "parent": "4b40ef1a-de18-4d71-8825-2ef16b502cd0",
298
              "uuid": "658b8768-55b8-45b5-99b3-f03ba252acb7"
299
            }
300
          ]
301
        }
302
      }
303
    }
304
  }
305
} 
306 12 Denis Kildishev
</code></pre>
307 23 Denis Kildishev
308
6.5. Получение единичного ресурса
309
Method:
310
GET
311
Paths:
312 1 Denis Kildishev
http://localhost:9988/projects/someproject/resources/ed612ae4-ced3-408c-8d64-66d87981611f/subpath.xhtml
313 23 Denis Kildishev
или
314
http://localhost:9988/projects/someproject/resources/ed612ae4-ced3-408c-8d64-66d87981611f/images/1.jpg
315
Содержат имя проекта {someproject}, uuid узла {ed612ae4-ced3-408c-8d64-66d87981611f} и путь к ресурсу относительно папки {nodeId}_resources.
316 26 Denis Kildishev
Стоит отметить что если в описании присутствует конструкция вида {node.resURL}/{img}[пример src="{node.resURL}/RTOS_cf.png"] то для _description путь к картинке фактически будет составлять {nodeId}_resources/_description/{img}[src="...RTOS_CONTROL_FLOW_resources\_description\RTOS_cf.png"]
317 23 Denis Kildishev
318 45 Denis Kildishev
7. Установка свойств (updated 1.4)
319 12 Denis Kildishev
Method:
320 27 Denis Kildishev
PUT
321 1 Denis Kildishev
Datatype:
322 12 Denis Kildishev
multipart/form-data или application/json
323 14 Denis Kildishev
Path:
324 12 Denis Kildishev
http://localhost:9988/projects/{TEST}/nodes/{uuid_of_node}/attributes/
325 1 Denis Kildishev
В теле запроса передаются значения свойств которые требуется изменить. Пример запроса ниже. Значение свойств которые не переданы в запросе остаются неизмеными. Сами свойства передаются через application/json поле "input". Изображения передаются в виде прикрепленных файлов в поле images.//TODO добавить пример.
326 17 Denis Kildishev
При использовании типа application/json вместо multipart/form-data свойства передаются непосредственно в теле запроса
327 45 Denis Kildishev
Стоит отметить, что устанавливается значение соответсвующее выдаче rawValue, то есть с использованием конструкций вида {val}. Если установить значения после подстановки, то в результате эти данные будут утеряны
328 12 Denis Kildishev
<pre><code class="javascript">
329
{
330
  "attributes":
331
    {
332
      "test":
333
        {
334
          "value":"2"
335
        },
336
      "test2":
337
        {
338
          "value":"3", "type": "INT"
339
        }
340
    }
341
}
342
</code></pre>
343
Возвращает текущий набор видимых распологающихся в узле свойств
344
<pre><code class="javascript">
345
{
346
  "success": true,
347
  "result": {
348
    "attributes": {
349
      "test2": {
350
        "value": "3",
351
        "type": "INT"
352
      },
353
      "_index": {
354
        "value": "8",
355
        "type": "STRING"
356
      },
357
      "test": {
358
        "value": "2",
359
        "type": "STRING"
360
      },
361
      "_tags": {
362
        "valuesType": "STRING",
363
        "value": [
364
          {
365
            "value": "section_Архитектура_ПО"
366
          }
367
        ],
368
        "type": "LIST"
369
      },
370
      "_type": {
371
        "value": "Requirement",
372
        "type": "STRING"
373
      },
374
      "_id": {
375
        "value": "Архитектура ПО",
376
        "type": "STRING"
377
      }
378
    }
379
  }
380
}
381
</code></pre>
382 1 Denis Kildishev
383 27 Denis Kildishev
7b. Пример установки картинки
384
Запрос
385
http://127.0.0.1:9988/projects/TEST/nodes/4db0fbf4-f383-4740-9d72-891ef112f742/attributes
386
Метод
387
PUT
388
Тип значения
389
multipart/form-data
390
Два поля в содержимом
391
text part с именем input, тип application/json
392
{   "attributes":     {       "_description":         {         "type":"HTML",  "value":"2<img src='example.png'/>"          }     } }
393
file part с именем images, загружена картинка example.png
394
если нужно больше изображений то следует добавить еще полей с именем images.
395
396 12 Denis Kildishev
8. Замена свойств
397 27 Denis Kildishev
Аналогичен 7, отличается использованием метода POST. Удаляет все свойства которые не перечисленны в запросе
398 12 Denis Kildishev
399
9. Удаление свойств
400
Method:
401
DELETE
402
Path:
403
http://localhost:9988/projects/{TEST}/nodes/{n}/attributes/
404
{TEST} - имя проекта
405
{n} - uuid узла
406
В теле запроса передаются все имена свойств которые требуется удалить в текстовом виде с разделителем ';'. Пример
407
_name;attributeName
408
Результат включают в себя список оставшихся свойств. 
409
Пример выдачи
410
411
<pre><code class="javascript">
412
{
413 13 Denis Kildishev
  "success": true,
414
  "result": {
415
    "attributes": [
416
      "Вид",
417
      "Производное",
418
      "_index",
419
      "_tags",
420
      "_type",
421
      "_id",
422
      "ForeignID"
423
    ],
424
  }
425 1 Denis Kildishev
}
426
</code></pre>
427 14 Denis Kildishev
428 15 Denis Kildishev
10. Создание проекта
429
Method:
430
PUT
431
Path:
432
http://localhost:9988/projects/{new_name}
433
{new_name} - имя проекта
434
Возвращает 
435
<pre><code class="javascript">
436
{
437
  "success": true,
438
  "result": {}
439
}
440
</code></pre>
441
либо если проект уже существует 
442
<pre><code class="javascript">
443
{
444
  "success": false,
445
  "error": {
446
    "code": "project_exists",
447
    "message": "Specified project already exists",
448
    "extra": {}
449
  }
450
}
451
</code></pre>
452 16 Denis Kildishev
453
10. Удаление проекта
454
Method:
455
DELETE
456
Path:
457
http://localhost:9988/projects/{name}
458
{name} - имя проекта
459
Возвращает 
460
<pre><code class="javascript">
461
{
462
  "success": true,
463
  "result": {}
464
}
465
</code></pre>
466
либо если проект не найден
467
<pre><code class="javascript">
468
{
469
  "success": false,
470
  "error": {
471
    "code": "project_not_found",
472
    "message": "Specified project does not exists",
473
    "extra": {}
474
  }
475
}
476 1 Denis Kildishev
</code></pre>
477 17 Denis Kildishev
478
11. Создание узла
479
Method:
480
PUT
481
Path:
482
http://localhost:9988/projects/{project_name}/create
483
project_name - имя проекта
484
Datatype:
485 19 Denis Kildishev
multipart/form-data или application/json
486
Для multipart/form-data в теле содержится два поля - input содержит json с описанием узла, images содержит изображения.
487
Для application/json в теле содержится только json с описанием
488 17 Denis Kildishev
<pre><code class="javascript">
489
{
490
  "parent": "516bbbbc-babf-45d6-a146-61db334411be",
491
  "type":"Requirement",
492
  "id":"002",
493
  "attributes":{
494
    "test": {
495
      "value": "13d23",
496
      "type": "INT"
497
    },
498
    "_name": {
499
      "value": "{test} test 123"
500
    },
501
    "Ref": {
502
      "type": "REFERENCE",
503
      "value":"test"
504
    },
505
    "_description": {
506
      "value":"test desc <img src='strange.png' alt='strange.xcf'/>", "type":"HTML"
507
    }
508
  }
509
}
510
</code>
511
</pre>
512
id является опциональным, если его не указывать он будет формироваться автоматически
513
Пример возвращаемого значения
514
<pre><code class="javascript">
515
{
516
  "success": true,
517
  "result": {
518 1 Denis Kildishev
    "name": "13d23 test 123",
519 32 Denis Kildishev
    "id": "002",
520 17 Denis Kildishev
    "uuid": "fbc83670-6993-4baf-8c8c-0b98aaab8ab3",
521
    "parent": "1f6e9e4f-4f63-446b-bddd-15838c15c212",
522
    "attributes": {
523
      "Ref": {
524
        "value": "*Missing(Ref): 'test'",
525
        "type": "REFERENCE"
526
      },
527
      "test": {
528
        "value": "13d23",
529
        "type": "INT"
530
      },
531
      "_name": {
532
        "value": "13d23 test 123",
533
        "type": "STRING"
534
      },
535
      "_type": {
536
        "value": "Requirement",
537
        "type": "STRING"
538
      },
539
      "_id": {
540
        "value": "002",
541
        "type": "STRING"
542
      },
543
      "_description": {
544
        "value": "test desc <img src='strange.png' alt='strange.xcf'/>",
545
        "type": "HTML"
546
      }
547
    }
548
  }
549
}
550
</code>
551
</pre>
552 18 Denis Kildishev
553 1 Denis Kildishev
12. Удаление узла
554 18 Denis Kildishev
Method:
555 19 Denis Kildishev
DELETE
556 18 Denis Kildishev
Path:
557
http://localhost:9988/projects/{project_name}/node
558
project_name - имя проекта
559
В теле в виде текста содержится идентефикатор узла, например UUID, но можно использовать и другие способы идентефикации
560
Пример
561
<pre><code class="javascript">
562
03745ff6-6f9f-4517-b011-c92ca6081a47
563
</code>
564
</pre>
565
Пример удачного удаления. Возвращается иерархия на уровне родителя удаленного узла
566
<pre><code class="javascript">
567
{
568
  "success": true,
569
  "result": {
570
    "haveChildren": true,
571 1 Denis Kildishev
    "name": "Requirements",
572 32 Denis Kildishev
    "id": "Requirements",
573 18 Denis Kildishev
    "type": "Requirement",
574
    "uuid": "1f6e9e4f-4f63-446b-bddd-15838c15c212",
575
    "children": [
576
      {
577 1 Denis Kildishev
        "name": "002",
578 32 Denis Kildishev
        "id": "002",
579 18 Denis Kildishev
        "type": "Requirement",
580
        "uuid": "fbc83670-6993-4baf-8c8c-0b98aaab8ab3"
581
      },
582
      {
583 1 Denis Kildishev
        "name": "004",
584 32 Denis Kildishev
        "id": "004",
585 18 Denis Kildishev
        "type": "Requirement",
586
        "uuid": "fb594248-0739-4b74-9c82-7c6d84e09e18"
587
      },
588
      {
589 1 Denis Kildishev
        "name": "005",
590 32 Denis Kildishev
        "id": "005",
591 18 Denis Kildishev
        "type": "Requirement",
592
        "uuid": "90ae2683-d4c7-4a97-ae03-255f449f9318"
593
      },
594 1 Denis Kildishev
      {
595
       "name": "006",
596 32 Denis Kildishev
       "id": "006",
597 20 Denis Kildishev
       "type": "Requirement",
598
       "uuid": "2ce727b8-0740-4344-988f-3155d7cea5f2"
599
      },
600
      {
601 1 Denis Kildishev
        "name": "007",
602 32 Denis Kildishev
        "id": "007",
603 20 Denis Kildishev
        "type": "Requirement",
604
        "uuid": "40155667-942e-43a6-9861-3c5b05adccfb"
605
      },
606
    ],
607
  }
608
}
609 18 Denis Kildishev
</code>
610
</pre>
611
Пример с отсутствующим узлом
612
<pre><code class="javascript">
613
{
614
  "success": false,
615
  "error": {
616
    "code": "qid_not_found",
617
    "message": "Specified QID does not exists",
618
    "extra": {}
619
  }
620
}
621
</code>
622 1 Denis Kildishev
</pre>
623 20 Denis Kildishev
624
13. Перемещение узла
625
Method:
626
POST
627
Path:
628
http://localhost:9988/projects/{project_name}/nodes/{uuid}/move
629
project_name - имя проекта
630
uuid - идентефикатор узла который требуется переместить
631
В теле содержится json с описанием параметров переноса
632
Пример
633
<pre><code class="javascript">
634
{
635
  "parent":"2ce727b8-0740-4344-988f-3155d7cea5f2",
636
  "node":"90ae2683-d4c7-4a97-ae03-255f449f9318",
637
  "position":"1"
638
}
639
</code>
640
</pre>
641
parent - указание на нового родителя
642
node и position - опциональные поля для того чтобы переместить узел в определенное место, могут не включаться в запрос
643
node при указании задает узел относительно которого нужно определить новую позицию
644
position может принимать значение <0 или >=1. Если он <0 то узел будет перемещен на позицию до целевого узла, если >=0 то после.
645
Пример удачного удаления. Возвращается иерархия на уровне нового родителя узла
646
<pre><code class="javascript">
647
{
648
  "success": true,
649
  "result": {
650
    "haveChildren": true,
651 1 Denis Kildishev
    "name": "Requirements",
652 32 Denis Kildishev
    "id": "Requirements",
653 20 Denis Kildishev
    "type": "Requirement",
654
    "uuid": "1f6e9e4f-4f63-446b-bddd-15838c15c212",
655
    "children": [
656
      {
657 1 Denis Kildishev
        "name": "002",
658 32 Denis Kildishev
        "id": "002",
659 20 Denis Kildishev
        "type": "Requirement",
660
        "uuid": "fbc83670-6993-4baf-8c8c-0b98aaab8ab3"
661
      },
662
      {
663 1 Denis Kildishev
        "name": "004",
664 32 Denis Kildishev
        "id": "004",
665 20 Denis Kildishev
        "type": "Requirement",
666
        "uuid": "fb594248-0739-4b74-9c82-7c6d84e09e18"
667
      },
668
      {
669 1 Denis Kildishev
        "name": "005",
670 32 Denis Kildishev
        "id": "005",
671 20 Denis Kildishev
        "type": "Requirement",
672
        "uuid": "90ae2683-d4c7-4a97-ae03-255f449f9318"
673
      },
674
      {
675 1 Denis Kildishev
       "name": "006",
676 32 Denis Kildishev
       "id": "006",
677 20 Denis Kildishev
       "type": "Requirement",
678
       "uuid": "2ce727b8-0740-4344-988f-3155d7cea5f2"
679
      },
680
      {
681 1 Denis Kildishev
        "name": "007",
682 32 Denis Kildishev
        "id": "007",
683 20 Denis Kildishev
        "type": "Requirement",
684
        "uuid": "40155667-942e-43a6-9861-3c5b05adccfb"
685
      },
686
    ],
687
  }
688
}
689 21 Denis Kildishev
</code>
690
</pre>
691 24 Denis Kildishev
692
14. Начало транзакции
693
Method:
694
POST
695
Path:
696
http://localhost:9988/projects/{project_name}/startTransaction
697
Тело содержить имя транзакиции в виде plaint текста, обычно включает имя проекта
698
project_name - имя проекта
699
Начинает транзакцию с набором действий которые впоследствии можно отменить
700
701
15. Коммит транзакции
702
Method:
703
POST
704
Path:
705
http://localhost:9988/projects/{project_name}/commitTransaction
706
project_name - имя проекта
707
Применяет транзакцию
708
709
16. Откат транзакции
710
Method:
711
POST
712
Path:
713
http://localhost:9988/projects/{project_name}/rollbackTransaction
714
project_name - имя проекта
715
Отменяет действие транзакции и возвращает все в состояние до начала транзакции
716
717
17. Отмена прошлой транзакции
718
Method:
719 25 Denis Kildishev
GET
720 24 Denis Kildishev
Path:
721 25 Denis Kildishev
http://localhost:9988/projects/undo
722
Отменяет предидущую транзакцию.
723 1 Denis Kildishev
724
18. Возврат отмененной транзакции
725
Method:
726 25 Denis Kildishev
GET
727 1 Denis Kildishev
Path:
728 25 Denis Kildishev
http://localhost:9988/projects/redo
729
Возвращает отмененную транзакцию.
730
731
19. Список действий к отмене
732
Method:
733
GET
734
Path:
735
http://localhost:9988/projects/undoactions
736 1 Denis Kildishev
Получение списка действий которые можно отменить.
737 25 Denis Kildishev
Пример ответа
738 28 Denis Kildishev
<pre><code class="javascript">
739 25 Denis Kildishev
{
740
  "success" : true,
741
  "result" : {
742
    "transactions" : [ "Move Element", "Move Element" ]
743 1 Denis Kildishev
  }
744
}
745 28 Denis Kildishev
</code>
746
</pre>
747 25 Denis Kildishev
748
20. Список действий к возвращению
749
Method:
750
GET
751
Path:
752
http://localhost:9988/projects/redoactions
753 1 Denis Kildishev
Получение списка действий которые можно вернуть.
754 25 Denis Kildishev
Пример ответа
755 28 Denis Kildishev
<pre><code class="javascript">
756 25 Denis Kildishev
{
757
  "success" : true,
758
  "result" : {
759
    "transactions" : [ "Move Element", "Move Element" ]
760 1 Denis Kildishev
  }
761
}
762 28 Denis Kildishev
</code>
763
</pre>
764
765 30 Denis Kildishev
21. Получение связей для узлов
766
Method:
767
POST
768
Path:
769
http://localhost:9988/projects/{project_name}/getlinks
770
project_name - имя проекта
771
В теле запроса список идентификаторов узлов для которых требуется получить связи разделенный ;(например uuid ов)
772
Возвращает список связей и узлов если связи удачно разрешились. Пример возвращаемого значения для узла 99bf5072-822a-41a8-bb54-eb4755773e84.
773
<pre><code class="javascript">
774
{
775
  "success": true,
776
  "result": {
777
    "links": {
778
      "99bf5072-822a-41a8-bb54-eb4755773e84": {
779
        "linkedByTerms": {
780
          "uintptr_t": [
781
            {
782 1 Denis Kildishev
              "name": "JetConfigTreeGet_UINTPTR",
783 32 Denis Kildishev
              "id": "001",
784 30 Denis Kildishev
              "type": "TextNode",
785
              "parent": "c4ffcef4-2926-4c50-9d63-b5fe5ecf142f",
786
              "externalId": "3326",
787
              "uuid": "cda13be2-e8f5-4f28-9662-d4a83d2280d2"
788
            }
789
          ],
790
        },
791
        "linkedByRelations": {
792
          "term-uintptr_t": [
793
            {
794 1 Denis Kildishev
              "name": "JetConfigTreeGet_UINTPTR",
795 32 Denis Kildishev
              "id": "005",
796 30 Denis Kildishev
              "type": "TextNode",
797
              "parent": "c4ffcef4-2926-4c50-9d63-b5fe5ecf142f",
798
              "externalId": "3326",
799
              "uuid": "cda13be2-e8f5-4f28-9662-d4a83d2280d2"
800
            }
801
          ],
802
        }
803
      }
804
    }
805
  }
806
}
807
</code>
808
</pre>
809
Возвращаемое значение представляет собой объект links в котором расположен словарь uuid->связи. Информация о связях заключена в 4 подгруппах. Префикс linkTo обозначают исходящие ссылки, linkedBy входящие
810
linkToTerms
811
linkedByTerms
812
linkToRelations
813
linkedByRelations
814
Суффиксы обозначают вид связи - связь по свойствам Relations и связь по определению и использованию терминов Terms.
815
Подробнее про термины можно прочитать в доках http://requality.org/ru/glossary.ru.html#glossary_term
816
817 31 Denis Kildishev
22. Получить список определений перечисляемцых типов
818
Method:
819
GET
820
Path:
821
http://localhost:9988/projects/{project_name}/enumDefinitions
822
project_name - имя проекта
823
Возвращает для выбранного проекта список доступных определений перечисляемых типов в формате 
824
enumDefinitions:{словарь имя_перечисления->опредление}
825
где определение это {valuesType:тив,value:[значения]}
826
значения - набор пар {value:значение, comment:комментарий}
827
значение имеет тип определенный в valuesType. На данный момент поддерживаются только перечислимые типы со строками
828
комментарий - строка дополнительно описывающая значение. При этом на данный момент обычно пуста(null в выдаче на данный момент)
829
Пример выдачи значений
830
<pre><code class="javascript">
831
{
832
  "success": true,
833
  "result": {
834
    "enumDefinitions": {
835
      "Test": {
836
        "valuesType": "STRING",
837
        "values": [
838
          {
839
            "value": "val01",
840
            "comment": null
841
          },
842
          {
843
            "value": "val02",
844
            "comment": null
845
          }
846
        ]
847
      },
848
      "Test2": {
849
        "valuesType": "STRING",
850
        "values": [
851
          {
852
            "value": "val",
853
            "comment": null
854
          }
855
        ]
856
      }
857
    }
858
  }
859
}
860
</code>
861
</pre>
862 30 Denis Kildishev
863 33 Denis Kildishev
23. Поиск узлов по строке
864
Method:
865
POST
866
Path:
867
http://localhost:9988/projects/{project_name}/search
868
project_name - имя проекта
869 34 Denis Kildishev
В теле запроса передается следующее.
870
<pre><code class="javascript">
871
{
872
	"request":"A",
873
	"attributes":[],
874 35 Denis Kildishev
        "caseSensitive":"false",
875 34 Denis Kildishev
	"rootNode":"/Requirements"
876
}
877
</code>
878 1 Denis Kildishev
</pre>
879 35 Denis Kildishev
request - сам запрос, в attributes передается список имен свойств, в rootNode - корень поиска,
880
caseSensitive - запрос на строгий поиск по регистру при true
881 33 Denis Kildishev
Возвращает для выбранного проекта узлы для которых указанная подстрока есть в одном из публичных свойств. 
882
Пример выдачи значений
883
<pre><code class="javascript">
884
{
885
  "success": true,
886
  "result": {
887
    "nodes": [
888
      {
889
        "name": "test",
890
        "uuid": "c4ffcef4-2926-4c50-9d63-b5fe5ecf142f",
891
        "sequentialId": "11040"
892
      },
893
      {
894
        "name": "test2",
895
        "uuid": "cda13be2-e8f5-4f28-9662-d4a83d2280d2",
896
        "sequentialId": "11041"
897
      }
898
    }
899
  }
900
}
901
</code>
902
</pre>
903
904 36 Denis Kildishev
Отчеты.
905
 Получение настроек генерации отчетов
906
В рамках работы инструмента возможно генерировать отчеты по одному из доступных шаблонов.
907
Для этого сначала создается объект с настройками генерации а затем по нему становится возможным генерировать экземпляры отчетов
908
Для настроек генерации можно задавать свойсва также как с другими узлами
909
910
911 37 Denis Kildishev
24. Вызов генерации отчета (!внимание - генерируется только 1 отчет за раз)
912 36 Denis Kildishev
Method:
913
POST
914
Path:
915 1 Denis Kildishev
http://localhost:9988/projects/{project}/reportSettings/{r}/generate
916
{r}-uuid настроек генерации
917 37 Denis Kildishev
Возвращает ссылку на новый экземпляр отчета по шаблону, процесс генерации запускается
918 41 Denis Kildishev
919
<pre><code class="javascript">
920 1 Denis Kildishev
{
921
  "success": true,
922
  "result": {
923 36 Denis Kildishev
    "id": {
924 1 Denis Kildishev
      "qid": "/Reports/001(2021-10-13_22-41-23)",
925 36 Denis Kildishev
      "uuid": "aab07d4f-a79a-45f8-ba95-32cddc6b58f8",
926
      "uv": "Reports/001(2021-10-13_22-41-23)"
927
    },
928
    "href": null
929
  }
930
}
931 41 Denis Kildishev
</code></pre>
932 36 Denis Kildishev
933 37 Denis Kildishev
25. Проверка статуса генерации отчета
934 36 Denis Kildishev
Method:
935 37 Denis Kildishev
POST
936 36 Denis Kildishev
Path:
937 37 Denis Kildishev
http://localhost:9988/projects/{project}/reports/{r}/generationStatus
938
Возвращает состояние генерации отчета
939 41 Denis Kildishev
<pre><code class="javascript">
940 36 Denis Kildishev
{
941
  "success": true,
942
  "result": {
943 37 Denis Kildishev
    "percentage": 0,
944
    "task": "init main generation - arch"
945
  }
946
}
947 41 Denis Kildishev
</code></pre>
948 37 Denis Kildishev
task имя выполняемой задачи
949
percentage - примерный общий процент
950
Если генерация отчета завершена в task записывается "generation over"
951 36 Denis Kildishev
952 37 Denis Kildishev
26. Получение полного содержимого отчета в виде zip архива(после генерации)
953 36 Denis Kildishev
Method:
954
GET
955
Path:
956
http://localhost:9988/projects/{project}/reports/{r}/export
957
Возвращает multipart/mixed
958
В теле записана длина архива и зип архив с содержимым отчета
959
960 37 Denis Kildishev
27. Просмотр содержимого отчета без ресурсов(после генерации)
961 36 Denis Kildishev
Method:
962
GET
963
Path:
964
http://localhost:9988/projects/{project}/reports/{r}
965
Возвращает html
966
967 38 Denis Kildishev
28. Получение списка шаблонов отчетов и их групп
968
Method:
969
GET
970
Path:
971
http://localhost:9988/projects/{project}/reportSettings/templates
972
Возвращает в формате
973
<pre><code class="javascript">
974
{
975
  "success": true,
976
  "result": [
977
    {
978
      "id": "typical",
979
      "type": "group",
980
      "name": "Отчёты для решения типовых задач",
981
      "description": "Отчеты для решения типовых задач.",
982
      "children": [
983
        {
984
          "id": "typical:com.unitesk.requality.reports.tableview",
985
          "type": "template",
986
          "name": "Чтение требований",
987
          "description": "",
988
          "children": null
989
        },...
990
      ]
991
    },...
992
  ]
993
}
994
</code></pre>
995
id - id группы шаблонов или шаблона, id шаблона включает id группы
996
type: template или group, шаблон или группа
997
name - отображаемое имя группы или шаблона
998
description - описание группы или шаблона
999
children - список потомков
1000
1001
29. Получение информации по используемым в определенном шаблоне параметам
1002
Method:
1003
GET
1004
Path:
1005
http://localhost:9988/projects/{project}/reportSettings/templates/{templateId}
1006
Возвращает информацию об определенном шаблоне и используемых в нем параметрах. Пример для шаблона com.unitesk.requality.reports.revision
1007 40 Denis Kildishev
1008
<pre><code class="javascript">
1009 38 Denis Kildishev
{
1010
  "success" : true,
1011
  "result" : [ {
1012
    "name" : "simplifiedAttrs",
1013
    "description" : "Use siplified notation for attribtues",
1014
    "type" : "BOOL",
1015
    "defValue" : "true",
1016
    "paramDataSource" : null,
1017
    "attributes" : null
1018
  }, {
1019
    "name" : "isHTML",
1020
    "description" : "If true display html instead of raw markup",
1021
    "type" : "BOOL",
1022
    "defValue" : "true",
1023
    "paramDataSource" : null,
1024
    "attributes" : null
1025
  }, {
1026
    "name" : "sideBySide",
1027
    "description" : "If true enables special mode for comparation - shows version before and after near side by site in a single row.",
1028
    "type" : "BOOL",
1029
    "defValue" : "false",
1030
    "paramDataSource" : null,
1031
    "attributes" : null
1032
  }, {
1033
    "name" : "revisonPrev",
1034
    "description" : "Previous revision for comparation. Needs to be more recent than revisionCur. Also may be HEAD or '' for workspace.",
1035
    "type" : "REVISION,STRING",
1036
    "defValue" : "HEAD",
1037
    "paramDataSource" : "_repoTreePagedVersion",
1038
    "attributes" : null
1039
  }, {
1040
    "name" : "revisonCur",
1041
    "description" : "Next revision for comparation. Empty value is workspace version. Needs to be older than revisionPrev. Also may be HEAD or '' for workspace.",
1042
    "type" : "REVISION,STRING",
1043
    "defValue" : "",
1044
    "paramDataSource" : "_repoTreePagedVersion",
1045
    "attributes" : null
1046
  } ]
1047 1 Denis Kildishev
}
1048 40 Denis Kildishev
</code></pre>
1049
1050 38 Denis Kildishev
result содержит информацию по используемым в шаблоне параметрам. name - имя параметра, description - описание параметра, type - описание типов с разделителем в виде ",". Последний из типов всегда является одним из стандартных типов AttributeType(STRING, LIST и т.д.). При этом LIST использует нотацию LIST[TYPE], например LIST[STRING] или LIST[LIST[STRING]]. Для не стадартных типов могут быть созданы отдельные редакторы и обработчики. Для REVISION, например, предпологается использование источника данных _repoTreePagedVersion и представляет собой выбор ревизии из списка доступных.
1051
defValue - значение по умолчанию, имеет стандартный тип из type(самый правый)
1052
paramDataSource - источник данных для параметра, можно получить данные по запросу
1053
attributes - описание атрибутов в виде которых хранится параметр. При этом по умочанию параметр хранится как атрибут с именем, типом и значением аналогичным параметру
1054
1055
30.
1056
Method:
1057 42 Denis Kildishev
POST
1058 38 Denis Kildishev
Path:
1059
http://localhost:9988/projects/{project}/nodes/{node}/dataSources/{dataSourceId}
1060
dataSourceId - id источника данных, например _repoTreePagedVersion
1061
node - uuid определенного узла, например, настроек генерации отчета
1062
project - имя проекта
1063
Возвращается список значений по источнику данных
1064 1 Denis Kildishev
Например, для _repoTreePagedVersion
1065 40 Denis Kildishev
1066
<pre><code class="javascript">
1067 38 Denis Kildishev
{
1068
  "success": true,
1069
  "result": {
1070
    "values": {
1071
      "value": [
1072
        {
1073
          "value": {
1074
            "branch": {
1075
              "value": "refs/heads/master"
1076
            },
1077
            "parents": {
1078
              "value": "069d87f22753296191fa44821a26e6d0a33e7a88"
1079
            }
1080
          },
1081
          "valuesType": "STRING"
1082
        },
1083
        {
1084
          "value": {
1085
            "author": {
1086 39 Denis Kildishev
              "value": "name [email]"
1087 38 Denis Kildishev
            },
1088
            "branch": {
1089
              "value": "refs/heads/master"
1090
            },
1091
            "date": {
1092
              "value": "2022-01-16 01:59:06"
1093
            },
1094
            "fullMessage": {
1095
              "value": "[#2209][#101]Descr.\n\n"
1096
            },
1097
            "parents": {
1098
              "value": "8b9f27d089faa5afefdb1dff21f14d1d43746a19"
1099
            },
1100
            "revision": {
1101
              "value": "069d87f22753296191fa44821a26e6d0a33e7a88"
1102
            },
1103
            "shortMessage": {
1104
              "value": "[#2209][#101] Short message..."
1105
            }
1106
          },
1107
          "valuesType": "STRING"
1108
        },...
1109
      ],
1110
      "valuesType": "MAP"
1111
    }
1112
  }
1113 1 Denis Kildishev
}
1114 40 Denis Kildishev
</code></pre>
1115 38 Denis Kildishev
values содержит описание значений по источнику данных, в примере они имеют тип MAP со значениями типа STRING
1116
поддерживается также режим постраничной выдачи
1117
http://localhost:9988/projects/{project}/nodes/{node}/dataSources/{dataSourceId}/page10_0
1118
в нотации page10_0 10 - количество записей на странице, 0 - номер старницы
1119 36 Denis Kildishev
1120 43 Denis Kildishev
31.
1121
Method:
1122
GET
1123
Path:
1124
http://localhost:9988/resources/getApplicationSession
1125
Возвращает строку, идентефикатор сессии сервера
1126
1127
32.
1128
Method:
1129
GET
1130
Path:
1131
http://localhost:9988/resources/listWebSocketProviders
1132
Возвращает json объект с состоянием веб сокетов для разных применений. Пример выдачи ниже     
1133
{
1134
  "success": true,
1135
  "result": "[{\"port\":\"9920\",\"name\":\"markup\",\"status\":\"STARTED\"},{\"port\":\"9922\",\"name\":\"reportView\",\"status\":\"STARTED\"},{\"port\":\"9924\",\"name\":\"review\",\"status\":\"STARTED\"},{\"port\":\"9923\",\"name\":\"moduleeditor\",\"status\":\"STARTED\"},{\"port\":\"9921\",\"name\":\"unieditor\",\"status\":\"STARTED\"}]"
1136
}
1137
port - занятый порт, name - имя, статус - состояние связанного объекта
1138
1139
33.
1140
Method:
1141
GET
1142
Path:
1143
http://localhost:9988/resources/getResourcesProviderStatus
1144
Возвращает json описывающий состояние сервера ресурсов от которого можно получить содержимое документов, отчетов, редактора требований, связанные ресурсы
1145
Пример выдачи
1146
{
1147
  "success": true,
1148
  "result": "{\"port\":\"9807\",\"status\":\"STARTED\"}"
1149
}
1150
1151
34.
1152
Method:
1153
GET
1154
Path:
1155
http://localhost:9988/resources/startSession/{project}:{doc}:{port}
1156
Начинает новую сессию взаимодействия с одним из серверов веб сокетов. project - имя проекта, doc - UUID документа, port - номер порта сервера 
1157
Возвращает строку - номер сессии 
1158
1159
35.
1160
Method:
1161
GET
1162
Path:
1163
http://localhost:9988/resources/stopSession/{session}
1164
Используется чтобы закрыть открытую на 34. сессию и освободить ресурсы
1165 36 Denis Kildishev
1166 44 Denis Kildishev
36.
1167
Method:
1168
GET
1169
Path:
1170
http://localhost:9988/projects/{project}/descendantsUUIDs/
1171
Возвращает список всех потомков узла /Requirements
1172
Пример выдачи
1173
{
1174
  "success" : true,
1175
  "result" : {
1176
    "nodes" : [ UUID1, ... ]
1177
}
1178
1179
37.
1180
Method:
1181
GET
1182
Path:
1183
http://localhost:9988/projects/{project}/descendantsUUIDs/{node}
1184
Возвращает список всех потомков узла с UUID node
1185
Пример выдачи
1186
{
1187
  "success" : true,
1188
  "result" : {
1189
    "nodes" : [ UUID1, ... ]
1190
}
1191 28 Denis Kildishev
E1. 
1192
Ошибка - проект не найден
1193
<pre><code class="javascript">
1194
{
1195
  "success": false,
1196
  "error": {
1197
    "code": "project_not_found",
1198
    "message": "Specified project does not exists",
1199
    "extra": {}
1200
  }
1201
}
1202
</code>
1203
</pre>
1204
1205
E2. 
1206
Ошибка - узел не найден
1207
<pre><code class="javascript">
1208
{
1209
  "success": false,
1210
  "error": {
1211
    "code": "node_not_found",
1212
    "message": "Specified node does not exists",
1213
    "extra": {}
1214
  }
1215
}
1216
</code>
1217
</pre>