Bulk REST API для активов и связей
Общее описание
Статья описывает REST API для пакетного создания и обновления активов и связей. API предназначено для использования внешними системами с целью массового создания/обновления большого количества записей активов и связей за оптимальное время.
Реализация API использует платформенный сервис массовых (BATCH) операций с записями.
Основные возможности:
Пакетная вставка и обновление активов
Пакетная вставка и обновление связей
Управление транзакционностью через параметр abortOnFailure
Получение детальной информации о результате каждой операции
Поддержка внешних идентификаторов (externalId) для интеграции с внешними системами
Для работы с API требуется аутентификация. Запросы должны содержать действительный токен доступа в заголовке.
API возвращает стандартные HTTP-статусы:
200 OK — успешное выполнение операции
400 Bad Request — ошибка валидации входных данных
401 Unauthorized — отсутствует или недействителен токен
403 Forbidden — недостаточно прав для выполнения операции
500 Internal Server Error — внутренняя ошибка сервера
Оптимальный размер пакета
Рекомендуется отправлять не более 500-1000 записей в одном пакете для производительности. Однако, оптимальный размер достигается опытным путем и зависит от количества атрибутов в записях, а также от доступных ресурсов сервера.
Обработка ошибок При установке abortOnFailure: true операция будет полностью отменена при первой же ошибке. Используйте этот режим, если важна атомарность операции.
Внешние идентификаторы
Используйте поле externalId для интеграции с внешними системами. Это позволяет избежать конфликтов идентификаторов и упрощает синхронизацию.
Обновление существующих записей
Для обновления существующего актива или связи обязательно указывайте etalonId. Без него будет создана новая запись.
Массовая вставка/обновление активов
POST /universe-backend/api/v1/dg/data/assets/upsert/bulk
Пример запроса:
{
"upserts": [ // Список активов для вставки/обновления
{
"etalonId": "", // Добавляем при обновлении
"typeName": "test_asset1",
"externalId": {
"externalId": "test2",
"sourceSystem": "test_system"
},
"lsn": 0,
"parentDraftId": 0,
"draftId": 0,
"operationType": "Direct",
"asset": {
"simpleAttributes": [
{
"targetEtalonId": null,
"valueId": "",
"unitId": "",
"displayValue": null,
"value": "2",
"type": "String",
"name": "id"
}
],
"arrayAttributes": [
{
"type": "String",
"name": "array_attr",
"value": ["a1", "a2"]
}
],
"complexAttributes": []
}
},
{
"etalonId": "",
"typeName": "test_asset1",
"externalId": {
"externalId": "test3",
"sourceSystem": "test_system"
},
"lsn": 0,
"parentDraftId": 0,
"draftId": 0,
"operationType": "Direct",
"asset": {
"simpleAttributes": [
{
"targetEtalonId": null,
"valueId": "",
"unitId": "",
"displayValue": null,
"value": "3",
"type": "String",
"name": "id"
}
],
"arrayAttributes": [
{
"type": "String",
"name": "array_attr",
"value": ["a1", "a2"]
}
],
"complexAttributes": []
}
}
],
"abortOnFailure": true, //Пакетная операция прерывается в случае ошибки при вставке любой записи
"withResult": true //Возвращать результат вставки/обновления - ключи и записи активов
}
Пример ответа:
{
"details": {
"info": [],
"warning": [],
"error": []
},
"results": [
{
"details": {
"info": [],
"warning": [],
"error": []
},
"keys": {
"createDate": "2026-06-23T04:52:28.178Z",
"updateDate": "2026-06-23T04:52:28.178Z",
"createdBy": "admin",
"updatedBy": "admin",
"etalonKey": {
"id": "55c24572-6ebf-11f1-a9c6-adee22ff4ab3",
"status": "ACTIVE"
},
"originKeys": [
{
"createDate": null,
"updateDate": null,
"createdBy": null,
"updatedBy": null,
"externalId": {
"externalId": "55c24574-6ebf-11f1-a9c6-adee22ff4ab3",
"sourceSystem": "unidata"
},
"enrichment": false,
"revision": 0,
"status": "ACTIVE"
},
{
"createDate": null,
"updateDate": null,
"createdBy": null,
"updatedBy": null,
"externalId": {
"externalId": "test2",
"sourceSystem": "test_system"
},
"enrichment": false,
"revision": 0,
"status": "ACTIVE"
}
],
"typeName": "test_asset1",
"lsn": null,
"published": false,
"lastEventUpdateDate": "2026-06-23T04:52:28.178Z",
"lastEventUpdateBy": "admin"
},
"etalon": {
"simpleAttributes": [ {
"name": "id",
"type": "String",
"targetEtalonId": null,
"displayValue": null,
"valueId": null,
"unitId": null,
"value": "2"
}],
"arrayAttributes": [ {
"name": "array_attr",
"type": "String",
"value": []
}],
"complexAttributes": [],
"etalonId": "55c24572-6ebf-11f1-a9c6-adee22ff4ab3",
"lsn": 0,
"version": 0,
"typeName": "test_asset1",
"status": "ACTIVE",
"operationType": "Direct",
"createDate": "2026-06-23T04:52:28.178+00:00",
"createdBy": "admin",
"updateDate": "2026-06-23T04:52:28.178+00:00",
"updatedBy": "admin"
}
},
{
"details": {
"info": [],
"warning": [],
"error": []
},
"keys": {
"createDate": "2026-06-23T04:52:28.201Z",
"updateDate": "2026-06-23T04:52:28.201Z",
"createdBy": "admin",
"updatedBy": "admin",
"etalonKey": {
"id": "55c552b8-6ebf-11f1-a9c6-adee22ff4ab3",
"status": "ACTIVE"
},
"originKeys": [
{
"createDate": null,
"updateDate": null,
"createdBy": null,
"updatedBy": null,
"externalId": {
"externalId": "test3",
"sourceSystem": "test_system"
},
"enrichment": false,
"revision": 0,
"status": "ACTIVE"
},
{
"createDate": null,
"updateDate": null,
"createdBy": null,
"updatedBy": null,
"externalId": {
"externalId": "55c552ba-6ebf-11f1-a9c6-adee22ff4ab3",
"sourceSystem": "unidata"
},
"enrichment": false,
"revision": 0,
"status": "ACTIVE"
}
],
"typeName": "test_asset1",
"lsn": null,
"published": false,
"lastEventUpdateDate": "2026-06-23T04:52:28.201Z",
"lastEventUpdateBy": "admin"
},
"etalon": {
"simpleAttributes": [ {
"name": "id",
"type": "String",
"targetEtalonId": null,
"displayValue": null,
"valueId": null,
"unitId": null,
"value": "3"
}],
"arrayAttributes": [ {
"name": "array_attr",
"type": "String",
"value": []
}],
"complexAttributes": [],
"etalonId": "55c552b8-6ebf-11f1-a9c6-adee22ff4ab3",
"lsn": 0,
"version": 0,
"typeName": "test_asset1",
"status": "ACTIVE",
"operationType": "Direct",
"createDate": "2026-06-23T04:52:28.201+00:00",
"createdBy": "admin",
"updateDate": "2026-06-23T04:52:28.201+00:00",
"updatedBy": "admin"
}
}
]
}
Массовая вставка/обновление связей
POST /universe-backend/api/v1/dg/data/relations/upsert/bulk
Пример запроса:
{
"upserts": [ // Список контекстов для вставки/обновления связей
{
"etalonId": "55c24572-6ebf-11f1-a9c6-adee22ff4ab3",
"typeName": "test_asset1",
"externalId": {
"externalId": "",
"sourceSystem": ""
},
"lsn": 0,
"parentDraftId": 0,
"relations": [ // Список связей для вставки/обновления
{
"relationType": "test",
"relationEtalonId": "",
"toEtalonId": "e1089c11-6ec0-11f1-a9c6-adee22ff4ab3",
"toTypeName": "test_asset2",
"toExternalId": {
"externalId": "",
"sourceSystem": ""
},
"toLsn": 0,
"draftId": 0,
"simpleAttributes": [
{
"targetEtalonId": null,
"valueId": "",
"unitId": "",
"displayValue": null,
"value": "name1",
"type": "String",
"name": "name"
}
],
"incoming": false
}
]
}
],
"abortOnFailure": true, //Пакетная операция прерывается в случае ошибки при вставке любой связи
"withResult": true //Возвращать результат вставки/обновления - ключи и атрибуты связей
}
Пример ответа:
{
"details": {
"info": [],
"warning": [],
"error": []
},
"etalons": [ {
"createDate": "2026-06-23T05:08:45.653Z",
"updateDate": "2026-06-23T05:08:45.653Z",
"createdBy": "admin",
"updatedBy": "admin",
"draftId": 0,
"etalonId": "d8d2b87c-0508-4f9f-92b8-7c0508bf9f7e",
"relationType": "test",
"status": "ACTIVE",
"fromEtalonId": "55c24572-6ebf-11f1-a9c6-adee22ff4ab3",
"toEtalonId": "e1089c11-6ec0-11f1-a9c6-adee22ff4ab3",
"fromTypeName": "test_asset1",
"toTypeName": "test_asset2",
"toDisplayName": "test21",
"fromDisplayName": "2",
"simpleAttributes": [ {
"name": "name",
"type": "String",
"targetEtalonId": null,
"displayValue": null,
"valueId": null,
"unitId": null,
"value": "name1"
}]
}]
}