Типы данных
В сообщениях обмена используются простые, переносимые типы значений — без специфики конкретной СУБД, языка программирования или учётной системы. Это сознательное ограничение модели: чем уже набор типов, тем меньше расхождений при сериализации/десериализации на стороне разных участников.
Каждый раздел ниже — отдельный тип; навигация по якорям.
Строка
Текст в кодировке UTF-8. Длина практически не ограничена шиной, но для очень длинных значений рекомендуется выносить их в файлы (см. Обмен файлами). Внутри строки допустимы любые символы Unicode, включая национальные алфавиты и эмодзи.
Целое число
Знаковое 64-битное число. Подходит для количеств, идентификаторов, кодов, порядковых номеров. Если значение по бизнес-смыслу не может быть отрицательным — это контролирует приложение, шина не различает «целое» и «целое неотрицательное».
Дробное число
Числа с плавающей точкой стандарта IEEE 754 двойной точности. Для финансовых сумм точность плавающей запятой не всегда приемлема — в таких случаях принято передавать значение в строке с фиксированной точкой ("123.45") и парсить как BigDecimal / Decimal на стороне получателя.
Логическое значение
Ровно два значения — true и false. Никаких «null = неизвестно» как третьего состояния: если нужно отличить «не установлено» от «явно ложно», поле делается опциональным.
Дата и время
Все даты и моменты времени передаются в формате ISO 8601.
- Дата без времени —
YYYY-MM-DD. Используется для значений, у которых нет естественного времени суток: дата документа, дата рождения, отчётная дата. - Дата-время —
YYYY-MM-DDThh:mm:ssZ. Всегда передаётся в UTC. - Пустая дата передаётся как пустая строка
"".
Длительность
Промежуток времени, в формате ISO 8601 (PT15M, P1DT2H). Используется реже остальных типов, обычно для конфигурационных полей.
GUID
Глобально уникальный идентификатор в каноническом виде 00000000-0000-0000-0000-000000000000 (8-4-4-4-12).
Ссылка на сущность
Указатель на бизнес-сущность в другой системе — например, ссылка на контрагента, товар, склад. Передаётся как массив структур {SystemID, SystemName, EntityID} — по той же схеме, что и основной идентификатор сообщения. Каждый элемент описывает идентификатор одной из систем-участников, знающих этот объект.
Такая форма нужна потому, что у одной и той же сущности в разных системах разные внутренние идентификаторы. Получатель берёт из массива тот элемент, где SystemID соответствует его идентификатору системы, и по EntityID находит объект в своей базе. Подробнее — в Идентификации объектов между системами.
Ссылки опираются на справочники, которыми участники обмениваются заранее: чтобы документ-заказ мог сослаться на контрагента, все участники должны уже знать этого контрагента. Поэтому в типовом обмене сначала синхронизируются справочники, потом начинают ходить документы.
Циклические ссылки запрещены. Объект не может ссылаться сам на себя через цепочку полей. Любая структура — это дерево, а не граф. Цикл превращает поиск ссылок в бесконечную отложенную обработку — см. Параллелизм.
Ссылка на файл
Указатель на файл во внешнем хранилище плюс метаданные (имя, размер, MIME-тип, контрольная сумма). См. Обмен файлами.
Объект (составной тип)
Набор именованных полей. Поля — это значения любых перечисленных здесь типов, в том числе вложенные объекты. Поля могут быть обязательными или опциональными; отсутствие опционального поля — допустимое состояние, не ошибка.
Массив
Упорядоченный список значений одного типа. Используется для табличных частей документов, множественных значений атрибута, списков подобъектов.
Перечисление
Значение из заранее объявленного фиксированного списка вариантов — обычно строка с заранее согласованным кодом ("NEW", "PAID", "CANCELLED"). Расширение перечисления — изменение контракта класса, а не локальное решение одной из сторон.
Двоичные данные
Бинарное содержимое в кодировке Base64. Допустимо для малых объёмов (миниатюры, контрольные суммы). Для файлов любого ощутимого размера — обмен файлами по ссылке, а не Base64 в payload.
Опциональность и null
Поле может быть обязательным (всегда должно присутствовать в сообщении) или опциональным (может отсутствовать). Опциональное поле, которое не передано, — это не «значение null», а «поле просто не пришло». Получатель должен явно обработать оба случая.
Если бизнес-смысл требует различать «значение неизвестно» от «значение явно отсутствует» — это два разных поля или специальный кодированный признак, а не игра с null.
Что НЕ поддерживается
- Циклические ссылки (см. выше).
- Полиморфные поля без явного дискриминатора. «Поле, в котором может быть число или объект» — антипаттерн: получатель не сможет надёжно его десериализовать.
- Бинарные блобы в payload (свыше нескольких сотен килобайт). Технически возможно, но противоречит модели — см. Структура сообщения / Размер.
- Локально-зависимые форматы. Дата с разделителем точкой, число с запятой как десятичным разделителем, строка в национальной кодировке — недопустимы. Все значения сериализуются в каноническом межсистемном виде.
Что дальше
- Структура сообщения обмена — где именно живут эти типы в составе сообщения.
- Классы сообщений — где фиксируется конкретный состав полей и их типов.
- Идентификация объектов между системами — как ссылки между системами образуют связную модель.
- Обмен файлами — почему бинарные данные передаются по ссылке.