REST-сервис meta-data-driven

Модуль предназначен для получения JSON-файлов от других информационных систем в свободной структуре данных. В результате работы запросов meta-data-driven структура данных JSON трансформируется в структуру, требуемую для корректной загрузки данных в Юниверс MDM.

Модуль помогает избегать этап ручной переработки структуры JSON в структуру, используемую Юниверс MDM. JSON-файлы могут приходить от информационной системы любого вида. Структура данных JSON может быть любой.

meta-data-driven заменяет стандартный способ загрузки данных в систему, загружая данные по своим алгоритмам и выполняя тем самым стороннюю интеграцию. Способы генерации внешнего ключа для модуля работают как для внешней интеграции.

Перечень запросов:

Базовый URL запросов: http://localhost:9080/universe-backend/api/

URL для Swagger: http://<хост>:<порт>/universe-backend/api/meta-data-driven/v1/api-docs?url=/universe-backend/api/meta-data-driven/v1/openapi.json#/Data%20schema/batchRequestSchema

Аутентификация

Все запросы требуют указания токена аутентификации. Для получения токена нужно выполнить следующий запрос:

  • Метод: POST

  • Путь запроса: {URL стенда}/universe-backend/api/v2/core/authentication/login

Пример запроса:

curl --location '{URL_стенда}/universe-backend/api/v2/core/authentication/login' \
--header 'Content-Type: application/json' \
--data '{
    "userName": "имя пользователя",
    "password": "пароль",
    "locale":"ru"
}'

Пример ответа:

{
  "token": "b2682a43-010f-46eb-a82a-43010f66eb1f"
}

Схема данных

Данные имеют динамическую структуру, зависящую от модели данных. Для получения структуры данных сервис предоставляет JSON схемы входящих/исходящих записей.

Схема входящих записей

Метод используется для получения описания модели данных реестра/справочника из MDM. В ответе содержится описание атрибутов и служебных атрибутов объекта.

  • Метод: GET

  • Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/schema/input/COUNTRY

Пример запроса:

curl -X 'GET' \
  'http://localhost:9081/universe-backend/api/meta-data-driven/v1/schema/input/COUNTRY' \
  -H 'accept: application/json' \
  -H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'
Пример ответа HTTP 200
{
  "$id": "/meta-data-driven/v1/schema/input/COUNTRY",
  "$schema": "http://json-schema.org/draft-07/schema",
  "description": "Страны",
  "type": "object",
  "properties": {
    "externalId": {
      "type": "string"
    },
    "sourceSystem": {
      "type": "string"
    },
    "patch": {
      "type": "boolean"
    },
    "attributes": {
      "type": "object",
      "description": "Страны",
      "properties": {
        "KOD": {
          "type": "string",
          "description": "Код страны ISO"
        },
        "NAME": {
          "type": "string",
          "description": "Краткое наименование"
        },
        "FULL_NAME": {
          "type": "string",
          "description": "Полное наименование"
        },
        "ENG_NAME": {
          "type": "string",
          "description": "Английское наименование"
        }
      },
      "required": [
        "KOD",
        "NAME"
      ]
    }
  }
}

Схема исходящих записей

Метод используется для получения описания нотификации. В ответе содержится описание атрибутов и служебных атрибутов нотификации.

  • Метод: GET

  • Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/schema/output/COUNTRY

Пример запроса:

curl -X 'GET' \
  'http://localhost:9081/universe-backend/api/meta-data-driven/v1/schema/output/COUNTRY' \
  -H 'accept: application/json' \
  -H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'
Пример ответа HTTP 200
{
  "$id": "/meta-data-driven/v1/schema/output/COUNTRY",
  "$schema": "http://json-schema.org/draft-07/schema",
  "type": "object",
  "properties": {
    "etalonId": {
      "type": "string"
    },
    "entityName": {
      "type": "string"
    },
    "externalKey": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "sourceSystem": {
          "type": "string"
        }
      }
    },
    "attributes": {
      "type": "object",
      "description": "Страны",
      "properties": {
        "KOD": {
          "type": "string",
          "description": "Код страны ISO"
        },
        "NAME": {
          "type": "string",
          "description": "Краткое наименование"
        },
        "FULL_NAME": {
          "type": "string",
          "description": "Полное наименование"
        },
        "ENG_NAME": {
          "type": "string",
          "description": "Английское наименование"
        }
      },
      "required": [
        "KOD",
        "NAME"
      ]
    }
  }
}

Схема batch-запроса

Метод используется для получения перечня объектов модели данных MDM. Описание каждого объекта можно получить в ответе на запрос "Схема входящих записей".

  • Метод: GET

  • Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/schema/batch-request

Пример запроса:

curl -X 'GET' \
  'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/schema/batch-request' \
  -H 'accept: application/json' \
  -H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'
Пример ответа HTTP 200
{
  "$id": "/meta-data-driven/v1/schema/batch-request",
  "$schema": "http://json-schema.org/draft-07/schema",
  "type": "object",
  "properties": {
    "resolveResult": {
      "type": "boolean"
    },
    "records": {
      "type": "object",
      "properties": {
        "OKV_S": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/OKV_S"
          }
        },
        "ContactType": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/ContactType"
          }
        },
        "COUNTRY": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/COUNTRY"
          }
        },
        "OKEI_S": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/OKEI_S"
          }
        },
        "OKOPF": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/OKOPF"
          }
        },
        "OKVED": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/OKVED"
          }
        },
        "OKFS": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/OKFS"
          }
        },
        "cars": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/cars"
          }
        },
        "Legal_Entity": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/Legal_Entity"
          }
        },
        "Person": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/Person"
          }
        },
        "article": {
          "type": "array",
          "items": {
            "$ref": "/meta-data-driven/v1/schema/input/article"
          }
        }
      }
    }
  }
}

Схема batch-ответа

Метод используется для получения перечня объектов, которые содержат описание нотификации для реестра/справочника MDM.

  • Метод: GET

  • Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/schema/batch-response

Пример ответа HTTP 200
{
  "$id": "/meta-data-driven/v1/schema/batch-response",
  "$schema": "http://json-schema.org/draft-07/schema",
  "type": "object",
  "properties": {
    "records": {
      "type": "object",
      "properties": {
        "OKV_S": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/OKV_S"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "ContactType": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/ContactType"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "COUNTRY": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/COUNTRY"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "OKEI_S": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/OKEI_S"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "OKOPF": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/OKOPF"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "OKVED": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/OKVED"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "OKFS": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/OKFS"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "cars": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/cars"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "Legal_Entity": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/Legal_Entity"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "Person": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/Person"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "article": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "record": {
                "$ref": "/meta-data-driven/v1/schema/output/article"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}

Работа с данными

Сохранение единичной записи

Метод используется для создания новой записи или для изменения существующей.

В качестве идентификатора используется связка externalId + source name. В случае отсутствия атрибута source name в запросе, запись будет создана/обновлена от имени universe.

Существует возможность обновить запись частично, передав только те атрибуты, которые требуется изменить. Для этого надо использовать параметр patch со значением true или false. Параметр true означает, что мы обновляем предыдущую ревизию (если запись имеет несколько ревизий) от имени источника, который указывается в запросе. Если мы выставим параметр на значение false то это будет значить, что мы обновляем последнюю ревизию записи (если запись имеет несколько ревизий).

  • Метод: POST

  • Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/{entity-name}

Пример запроса:

curl -X 'POST' \
  'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/OKOPF' \
  -H 'accept: application/json' \
  -H 'Authorization: fae5b2f0-2b1c-42db-a5b2-f02b1c52dbcd' \
  -H 'Content-Type: application/json' \
  -d '{
  "externalId": "my_unique_id_2",
  "attributes": {
          "KOD": 99998,
          "IS_ACTUAL": true,
          "NAME": "Наименование"
  }
}'

Пример ответа HTTP 200:

{
  "record": {
    "etalonId": "40c8610a-755f-11ed-9fbd-73aae866f4c6",
    "entityName": "OKOPF",
    "externalKey": {
      "id": "my_unique_id_2",
      "sourceSystem": "universe"
    },
    "attributes": {
      "KOD": 99998,
      "IS_ACTUAL": true,
      "NAME": "Наименование"
    },
   "relations": null
  },
  "details": []
}

Batch сохранение

Метод используется для массового создания новых записей или изменения существующих. В качестве идентификатора используется externalId.

  • Метод: POST

  • Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/save-batch

Пример запроса:

curl -X 'POST' \
  '{URL_стенда}/universe-backend/api/meta-data-driven/v1/data/save-batch' \
  -H 'accept: application/json' \
  -H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783' \
  -H 'Content-Type: application/json' \
  -d '{
  "records": {
    "OKOPF": [
      {
        "externalId": "my_unique_id",
        "attributes": {
          "KOD": 99999,
          "IS_ACTUAL": true,
          "NAME": "Наименование"
        }
      }
    ]
  },
  "resolveResult": true
}'

Пример ответа HTTP 200:

{
  "records": {
    "OKOPF": [
      {
        "record": {
          "etalonId": "1bc560e6-755a-11ed-be37-73aae866f4c6",
          "entityName": "OKOPF",
          "externalKey": {
            "id": "my_unique_id",
            "sourceSystem": "universe"
          },
          "attributes": {
            "KOD": 99999,
            "IS_ACTUAL": true,
            "NAME": "Наименование"
          },
          "relations": null
        },
        "details": []
      }
    ]
  }
}

Запрос записи по внешнему ключу

Метод используется для получения информации о записи. В качестве идентификатора используется связка externalId + source-system.

  • Метод: GET

  • Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/{entity-name}/{source-system}/{external-id}

Пример запроса:

curl -X 'GET' \
  'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/OKOPF/universe/eid_1' \
  -H 'accept: application/json' \
  -H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'

Пример ответа HTTP 200:

{
  "etalonId": "dcb81331-7165-11ed-969f-73aae866f4c6",
  "entityName": "OKOPF",
  "externalKey": {
    "id": "eid_1",
    "sourceSystem": "universe"
  },
  "attributes": {
    "KOD": 10001,
    "IS_ACTUAL": true,
    "NAME": "Наименование"
  },
  "relations": null
}

Запрос записи по эталонному ключу

Метод используется для получения информации о записи по etalonId.

  • Метод: GET

  • Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/{entity-name}/{etalon-id}

Пример простого запроса:

curl -X 'GET' \
  'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/OKOPF/dcb81331-7165-11ed-969f-73aae866f4c6' \
  -H 'accept: application/json' \
  -H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'

Пример ответа HTTP 200:

{
  "etalonId": "dcb81331-7165-11ed-969f-73aae866f4c6",
  "entityName": "OKOPF",
  "externalKey": {
    "id": "eid_1",
    "sourceSystem": "universe"
  },
  "attributes": {
    "KOD": 10001,
    "IS_ACTUAL": true,
    "NAME": "Наименование"
  },
  "relations": null
}

Пример запроса записи, которая содержит связь и простые атрибуты:

GET http://universe-mdm-ea:8082/universe-backend/api/meta-data-driven/v1/data/organizations/3910b197-8225-11ee-b6df-d37c61cbe6d3

HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive

{
  "etalonId": "3910b197-8225-11ee-b6df-d37c61cbe6d3",
  "entityName": "organizations",
  "externalKey": {
    "id": "30b62bb0-8225-11ee-a174-afd210c0bfe3",
    "sourceSystem": "universe"
  },
  "createAt": "2023-11-13T13:04:49.335",
  "updateAt": "2023-11-13T13:04:49.335",
  "attributes": {
    "head_patronymic": "Михайлович",
    "individual_entrepreneur": false,
    "Conmtacts": [],
    "contact_phone_number": "+7(978)493-03-20",
    "status_name": "",
    "head_position": "ИО директора",
    "head_first_name": "Алексей",
    "okopf_name": "Частные учреждения",
    "okfs_id": "34",
    "head_surname": "Ровнов",
    "okopf_id": "75500",
    "okfs_name": "Совместная частная и иностранная собственность",
    "full_name": "ООО Аврора",
    "okved_id": "97.00",
    "doc": [],
    "short_name": "Аврора",
    "status": "110"
  },
  "relations": {
    "organizations_bank_accounts_rel": [
      {
        "attributes": {},
        "ref": {
          "id": "306c821f-3aaf-11ef-805b-d37c61cbe6d3",
          "entityName": "bank_accounts"
        }
      }
    ]
  },
  "dataQuality": []
}
Пример запроса записи, которая содержит связь и классификатор
GET http://universe-mdm-ea:8082/universe-backend/api/meta-data-driven/v1/data/industrial/4c7d8788-8225-11ee-b6df-d37c61cbe6d3

HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive

{
  "etalonId": "4c7d8788-8225-11ee-b6df-d37c61cbe6d3",
  "entityName": "industrial",
  "externalKey": {
    "id": "42545d10-8225-11ee-9295-b94aeb0b8e88",
    "sourceSystem": "universe"
  },
  "createAt": "2023-11-13T13:05:21.896",
  "updateAt": "2023-11-13T13:05:21.896",
  "attributes": {
    "tons": 0.0,
    "mass": 1000.0,
    "name": "Станок деревообрабатывающий",
    "model": "FD-27638"
  },
  "relations": {
    "svyaz": [
      {
        "attributes": {},
        "ref": {
          "id": "82a0495a-35d6-11ee-a909-d37c61cbe6d3",
          "entityName": "persons"
        }
      }
    ]
  },
  "dataQuality": [],
  "classifiers": {
    "industrial_machine": {
      "milling": {
        "extensionProperties": {},
        "attributes": {
          "friq": 2000.0,
          "aspir": 75.0,
          "spindel": 30.0
        },
        "version": "industrial_machine"
      }
    },
    "mtr": {
      "trub": {
        "extensionProperties": {},
        "attributes": {},
        "version": "mtr"
      }
    }
  }
}
Пример запроса записи, которая содержит связь и комплексный атрибут
GET http://universe-mdm-ea:8082/universe-backend/api/meta-data-driven/v1/data/organizations/12932d10-32d2-11ee-98d5-d37c61cbe6d3

HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive

{
  "etalonId": "12932d10-32d2-11ee-98d5-d37c61cbe6d3",
  "entityName": "organizations",
  "externalKey": {
    "id": "04f1cae0-32d2-11ee-9485-9dc19d9f8732",
    "sourceSystem": "universe"
  },
  "createAt": "2023-08-04T14:20:34.407",
  "updateAt": "2023-08-04T14:20:34.407",
  "attributes": {
    "okopf_id": "75502",
    "okfs_name": "Совместная частная и иностранная собственность",
    "individual_entrepreneur": true,
    "full_name": "Общество с ограниченной ответственностью \"Ликар\"",
    "Conmtacts": [
      {
        "contact_type": "02",
        "contact_value": "+78655432654"
      },
      {
        "contact_type": "07",
        "contact_value": "likar@likar.com"
      }
    ],
    "status_name": "Регистрирующим органом принято решение о предстоящем исключении индивидуального предпринимателя из ЕГРИП (наличие оснований, предусмотренных подпунктом \"б\" пункта 2 статьи 22.4 Федерального закона от 08.08.2001 № 129-ФЗ \"О государственной регистрации юридических лиц и индивидуальных предпринимателей\")",
    "doc": [
      {
        "type": "паспорт",
        "numb": "235678"
      }
    ],
    "short_name": "ООО \"Ликар\"",
    "okopf_name": "Благотворительные учреждения",
    "okfs_id": "34",
    "status": "111"
  },
  "relations": {
    "organizations_addresses_rel": [
      {
        "attributes": {},
        "ref": {
          "id": "37784e69-530f-11ee-8ca2-d37c61cbe6d3",
          "entityName": "addresses"
        }
      }
    ]
  },
  "dataQuality": []
}

Обновление записи

Параметры запроса для patch = true

Формирование эталона записи в системе происходит в зависимости от весов систем-источников. В случае если веса равны, значения победившего атрибута становится равным значению самого свежего Origin. При обновлении записи, атрибуты обновляются информацией из системы bit.

В части интеграции, платформа предусматривает обновление только записи в целом. Указание значения по умолчанию в модели данных закладывает логику обработки входящих сообщений по интеграции. В таком случае, если логический атрибут не указан, то при расчете эталона будет выставлено значение по умолчанию.

Пример запроса:

curl -X 'POST' \
 'http://10.21.0.176:8082/universe-backend/api/meta-data-driven/v1/data/test_check' \
 -H 'accept: application/json' \
 -H 'Authorization: ab605d3f-7110-48e9-a05d-3f7110c8e976' \
 -H 'Content-Type: application/json' \
 -d '{
   "patch": true,
   "sourceSystem": "bit",
   "externalId": "test21214",
   "attributes": {
       "id": "test1111"
   }
  }'

Параметры запроса для patch = false

При patch = false атрибутам, которым не передалось значение в запросе - проставляется значение null. Значение установлено по умолчанию, из-за чего null меняется на него и становится самым новым атрибутом.

Если значение по умолчанию отсутствует, то передаваемый атрибут остается пустым и не участвует в консолидации. Таким образом, значение, которое вносили через UI остается самым новым и не заменяется на что-либо.

Пример запроса:

curl -X 'POST' \.
'http://10.21.0.176:8082/universe-backend/api/meta-data-driven/v1/data/test_check' \
-H 'accept: application/json' \
-H 'Authorization: ab605d3f-7110-48e9-a05d-3f7110c8e976' \
-H 'Content-Type: application/json' \
-d '{
  "patch": false,
  "sourceSystem": "bit",
  "externalId": "test212",
  "attributes": {
      "id": "test111",
      "id2": "test211"
  }
 }'

Удаление записи

Метод используется для логического удаления записи. В качестве идентификатора используется etalonId.

  • Метод: DELETE

  • Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/{entity-name}/{etalon-id}

Пример запроса:

curl -X 'DELETE' \
  'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/OKOPF/40c8610a-755f-11ed-9fbd-73aae866f4c6?wipe=false' \
  -H 'accept: */*' \
  -H 'Authorization: e555c773-c8e4-4698-95c7-73c8e4869865'

Создание записей со связями

Пример запроса на создание записи со связью:

{
    "externalId": "b1",
    "sourceSystem": "bit",
    "attributes": {
        "str": "b1"
    },
    "relations": {
        "many": [
            {
                "record": {
                    "externalId": "2b43df10-acae-11ef-a39d-67df0eb59c3c",
                    "sourceSystem": "universe"
                }
            }
        ]
    }
}

Пример ответа:

{
    "record": {
        "etalonId": "82a4e46c-b0b8-11ef-81ae-8f775b811cb4",
        "entityName": "entity",
        "externalKey": {
            "id": "b1",
            "sourceSystem": "bit"
        },
        "validFrom": "1900-01-01T00:00:00.000",
        "validTo": "2500-12-31T23:59:59.999",
        "createAt": "2024-12-02T14:19:58.408",
        "updateAt": "2024-12-02T14:19:58.408",
        "attributes": {
            "str": "b1"
        },
        "relations": {
            "many": [
                {
                    "attributes": {},
                    "ref": {
                        "id": "2c4dd534-acae-11ef-ae39-8f775b811cb4",
                        "entityName": "test"
                    },
                    "etalonId": "b354287b-b0b9-11ef-a3c7-8f775b811cb4",
                    "validFrom": "1900-01-01T00:00:00.000",
                    "validTo": "2500-12-31T23:59:59.999"
                }
            ]
        },
        "dataQuality": [],
        "classifiers": {}
    },
    "details": []
}

Пример запроса на создание записи со связью с несколькими периодами актуальности:

{
    "externalId": "b2",
    "sourceSystem": "bit",
    "attributes": {
        "str": "b2"
    },
    "relations": {
        "many": [
            {
                "record": {
                    "externalId": "2b43df10-acae-11ef-a39d-67df0eb59c3c",
                    "sourceSystem": "universe",
                    "validFrom": "1900-01-01T00:00:00.000",
                    "validTo": "2000-12-31T23:59:59.999"
                }
            },
            {
                "record": {
                    "externalId": "2b43df10-acae-11ef-a39d-67df0eb59c3c",
                    "sourceSystem": "universe",
                    "validFrom": "2001-01-01T00:00:00.000",
                    "validTo": "2500-12-31T23:59:59.999"
                }
            }
        ]
    }
}

Пример ответа:

{
    "record": {
        "etalonId": "d2c459e2-b153-11ef-8a86-8f775b811cb4",
        "entityName": "entity",
        "externalKey": {
            "id": "b2",
            "sourceSystem": "bit"
        },
        "validFrom": "1900-01-01T00:00:00.000",
        "validTo": "2500-12-31T23:59:59.999",
        "createAt": "2024-12-03T08:51:44.825",
        "updateAt": "2024-12-03T08:51:44.825",
        "attributes": {
            "str": "b2"
        },
        "relations": {
            "many": [
                {
                    "attributes": {},
                    "ref": {
                        "id": "2c4dd534-acae-11ef-ae39-8f775b811cb4",
                        "entityName": "test"
                    },
                    "etalonId": "d2c6cae6-b153-11ef-8a86-8f775b811cb4",
                    "validFrom": "2001-01-01T00:00:00.000",
                    "validTo": "2500-12-31T23:59:59.999"
                }
            ]
        },
        "dataQuality": [],
        "classifiers": {}
    },
    "details": []
}

Удаление связей

Удаление связей происходит при обновлении записи и может осуществляться двумя способами:

  • При указании в запросе etalonId связи;

  • Если etalonId связи не указывается, а прописываются toExternalId и toSourceSystem. В этом случае etalonId связи будет найден по ключам связанных записей.

Пример построения запроса:

{
    ...

    "relationsDeletes": {
        <имя_связи_1>: [
            {
                "etalonId": /* ETALON_ID связи */ ,
                "validFrom": /* Левая граница периода актуальности связи (необязательно, если указать будет происходить удаление периода связи) */ ,
                "validTo": /* Правая граница периода актуальности связи (необязательно, если указать будет происходить удаление периода связи) */
            },
            /* Прочие удаления эталонов связи <имя_связи_1> */
        ],
        <имя_связи_2>: [
            /* Удаления эталонов связи <имя_связи_2> */
        ]
    }
}

Удаление эталона созданной связи (по etalonId связи)

Пример запроса:

{
    "externalId": "b1",
    "sourceSystem": "bit",
    "attributes": {
        "str": "b1"
    },
    "relationsDeletes": {
        "many": [
            {
                "etalonId": "b354287b-b0b9-11ef-a3c7-8f775b811cb4"
            }
        ]
    }
}

Приметр ответа:

{
    "record": {
        "etalonId": "82a4e46c-b0b8-11ef-81ae-8f775b811cb4",
        "entityName": "entity",
        "externalKey": {
            "id": "b1",
            "sourceSystem": "bit"
        },
        "validFrom": "1900-01-01T00:00:00.000",
        "validTo": "2500-12-31T23:59:59.999",
        "createAt": "2024-12-02T14:28:29.570",
        "updateAt": "2024-12-02T14:28:29.570",
        "attributes": {
            "str": "b1"
        },
        "relations": {},
        "dataQuality": [],
        "classifiers": {}
    },
    "details": []
}

Удаление эталона связи (по toExternalId и toSourceSystem)

Пример запроса:

{
    "externalId": "b1",
    "sourceSystem": "bit",
    "attributes": {
        "str": "b1"
    },
    "relationsDeletes": {
        "many": [
            {
                "toExternalId": "2b43df10-acae-11ef-a39d-67df0eb59c3c",
                "toSourceSystem": "universe"
            }
        ]
    }
}

Пример ответа:

{
    "record": {
        "etalonId": "82a4e46c-b0b8-11ef-81ae-8f775b811cb4",
        "entityName": "entity",
        "externalKey": {
            "id": "b1",
            "sourceSystem": "bit"
        },
        "validFrom": "1900-01-01T00:00:00.000",
        "validTo": "2500-12-31T23:59:59.999",
        "createAt": "2024-12-02T14:28:29.570",
        "updateAt": "2024-12-02T14:28:29.570",
        "attributes": {
            "str": "b1"
        },
        "relations": {},
        "dataQuality": [],
        "classifiers": {}
    },
    "details": []
}

Удаление периода актуальности связи

Пример запроса:

{
    "externalId": "b2",
    "sourceSystem": "bit",
    "attributes": {
        "str": "b2"
    },
    "relationsDeletes": {
        "many": [
            {
                "etalonId": "d2c6cae6-b153-11ef-8a86-8f775b811cb4",
                "validFrom": "1900-01-01T00:00:00.000",
                "validTo": "2000-12-31T23:59:59.999"
            }
        ]
    }
}

Пример ответа:

{
    "record": {
        "etalonId": "d2c459e2-b153-11ef-8a86-8f775b811cb4",
        "entityName": "entity",
        "externalKey": {
            "id": "b2",
            "sourceSystem": "bit"
        },
        "validFrom": "1900-01-01T00:00:00.000",
        "validTo": "2500-12-31T23:59:59.999",
        "createAt": "2024-12-03T08:51:44.825",
        "updateAt": "2024-12-03T08:51:44.825",
        "attributes": {
            "str": "b2"
        },
        "relations": {
            "many": [
                {
                    "attributes": {},
                    "ref": {
                        "id": "2c4dd534-acae-11ef-ae39-8f775b811cb4",
                        "entityName": "test"
                    },
                    "etalonId": "d2c6cae6-b153-11ef-8a86-8f775b811cb4",
                    "validFrom": "2001-01-01T00:00:00.000",
                    "validTo": "2500-12-31T23:59:59.999"
                }
            ]
        },
        "dataQuality": [],
        "classifiers": {}
    },
    "details": []
}

Уведомление о состоянии записи

Обновленный модуль уведомления отправляет состояние записи редактируемого периода актуальности.

Для сообщений meta-driven, об уведомлении вставки и удаления были добавлены поля:

  • "validFrom" - дата начала периода актуальности;

  • "validTo" - дата окончания периода актуальности.

Пример сообщения meta-driven:

 {
   "etalonId": "0219297e-86e9-11ef-bd97-5bd86fbfa823",
   "entityName": "from",
   "externalKey": {
       "id": "fa5abd00-86e8-11ef-ba88-9915efe6d326",
       "sourceSystem": "universe"
   },
   "validFrom": "2001-01-01T00:00:00.000",
   "validTo": "2030-12-31T23:59:59.999",
   "createAt": "2024-10-10T09:21:46.838",
   "updateAt": "2024-10-10T09:21:46.838",
   "attributes": {
       "str": "настоящее"
   },
   "relations": {},
   "dataQuality": [],
   "classifiers": {}
}

Пример сообщения уведомления о вставке:

 {
   "id": "34234c71-d341-457f-b54a-a89e528b3681",
   "entityName": "from",
   "etalonId": "0219297e-86e9-11ef-bd97-5bd86fbfa823",
   "originId": "128b36f9-86e9-11ef-bd97-5bd86fbfa823",
   "timestamp": "2024-10-10T09:37:36.271967858",
   "type": "UPDATE",
   "attributes": {
       "str": "настоящее"
   },
   "lookupLinkAttributes": null,
   "relations": {},
   "classifiers": {},
   "recordChanges": null,
   "relationsChanges": null,
   "classificationsChanges": null,
   "validFrom": "2001-01-01T00:00:00.000",
   "validTo": "2030-12-31T23:59:59.999",
   "draftOperation": false
}

Пример сообщения уведомления об удалении:

 {
   "id": "558afaa2-0ce7-4a77-958e-60d84720bec6",
   "entityName": "from",
   "etalonId": "0219297e-86e9-11ef-bd97-5bd86fbfa823",
   "originId": "128b36f9-86e9-11ef-bd97-5bd86fbfa823",
   "timestamp": "2024-10-10T09:40:50.759418981",
   "type": "DELETE",
   "validFrom": "2001-01-01T00:00:00.000",
   "validTo": "2030-12-31T23:59:59.999",
   "draftOperation": false
}

Режим вставки комплексного атрибута (PATCH)

Включение функции регулируется флагом patch в UpsertRequestRO для REST API или в RecordInputRO для MetaDriven:

  • При patch=false новый экземпляр комплексного атрибута полностью перезапишет старый экземпляр (по умолчанию);

  • При patch=true новый экземпляр комплексного атрибута объединится со старым экземпляром. Функция опирается на использование ключевых атрибутов, поэтому их у обновляемых атрибутов обязательно, иначе вызовет исключение. Если у комплексного атрибута не задан ключевой атрибут в модели данных, то обновление перезапишет старый экземпляр (как при patch=false).

Пример запроса POST universe-backend/api/v2/data/atomic
  {
    "payload": {
        "org.unidata.mdm.rest.v2.data": {
            "patch": true,
            "dataRecord": {
                "etalonId": "fba32f80-9b71-11ef-8fe4-b1a622cc6d9c",
                "entityName": "entity",
                "namespace": "register",
                "validFrom": "1900-01-01T00:00:00.000Z",
                "validTo": "2500-12-31T23:59:59.999Z",
                "status": "ACTIVE",
                "simpleAttributes": [
                    {
                        "value": "abc",
                        "type": "String",
                        "name": "str"
                    }
                ],
                "complexAttributes": [
                    {
                        "name": "complex",
                        "nestedRecords": [
                            {
                                "simpleAttributes": [
                                    {
                                        "value": "code1",
                                        "type": "String",
                                        "name": "code"
                                    },
                                    {
                                        "value": "str1",
                                        "type": "String",
                                        "name": "str"
                                    }
                                ],
                                "complexAttributes": [],
                                "arrayAttributes": []
                            }
                        ]
                    }
                ],
                "arrayAttributes": [],
                "codeAttributes": []
            },
            "relationManyToMany": {
                "toUpdate": [],
                "toDelete": []
            },
            "relationReferences": {
                "toUpdate": [],
                "toDelete": []
            },
            "relationContains": {
                "toUpdate": [],
                "toDelete": []
            }
        }
    }
}

Пример запроса POST universe-backend/api/meta-data-driven/v1/data/{entity-name}:

 {
   "patch": true,
   "externalId": "efce7730-9b71-11ef-9e6c-0536b5d706e4",
   "sourceSystem": "universe",
   "validFrom": "1900-01-01T00:00:00.000",
   "validTo": "2500-12-31T23:59:59.999",
   "attributes": {
       "str": "abc",
       "complex": [
           {
               "str": "str1",
               "code": "code1",
               "int": 1
           }
       ]
   },
   "relations": {},
   "classifiers": {}
}