Границы OData в 1С
Обновлено 8 сентября 2026 г. · 14 мин чтения
Стандартный интерфейс OData в 1С отдаёт наружу справочники и документы, журналы документов, константы, перечисления, все виды регистров с их виртуальными таблицами, планы счетов, видов характеристик и видов расчёта, бизнес-процессы с задачами. Не отдаёт отчёты, обработки, команды, критерии отбора, регламентные задания, внешние источники данных и пользователей. Писать код для этого не нужно, платформа строит интерфейс из метаданных сама, начиная с версии 8.3.5, по спецификации OData 3.0.
Как интерфейс включается
Публикация состоит из двух частей, и их часто путают между собой. Сначала базу публикуют на веб-сервере из Конфигуратора и ставят в диалоге флажок «Публиковать стандартный интерфейс OData». Руководство разработчика называет два поддерживаемых веб-сервера — IIS и Apache версии 2.4 — и утилиту webinst, которой ту же публикацию делают из командной строки, без диалога. Имя публикации принято задавать латиницей, без пробелов.
Флажок в диалоге меняет ровно один атрибут в файле публикации default.vrd — enableStandardOData у тега <point>. Атрибут появился вместе с самим механизмом в 8.3.5, и на чужой уже опубликованной базе он отвечает на вопрос «интерфейс вообще включали?» быстрее, чем поход в Конфигуратор.
Сначала состав, иначе наружу не уходит ничего
Состав — это перечень объектов, видных снаружи, и указывают его отдельно от публикации. По умолчанию наружу не уходит ничего. Список пустой. Запрос к любому справочнику вернёт ошибку. Состав ставят либо кодом, методом УстановитьСоставСтандартногоИнтерфейсаOData(), либо в режиме предприятия — в типовых конфигурациях на БСП есть обработка «Настройка автоматического REST-сервиса» (в разных конфигурациях она лежит по-своему, «Администрирование» либо «Настройки» → «Синхронизация данных» → «Настройки стандартного интерфейса OData»). В конфигурации без БСП остаётся только метод.
Зависимости состав не подтягивает сам. Если для включённого объекта нужен доступ ещё и к подчинённым видам объектов, обработка выведет сообщение и предложит его включить, но сама наружу ничего не добавит. При установке составом из кода зависимости придётся перечислить руками.
Режим совместимости отменяет избирательность целиком, и документ изменений платформы 8.3.5 говорит об этом прямым текстом — в режиме совместимости с версией 8.3.4 через интерфейс OData доступны все объекты конфигурации, поддерживаемые механизмом, а метод установки состава работает только при отключённом режиме совместимости. На старой конфигурации «по умолчанию закрыто» превращается в «по умолчанию открыто целиком». Смотреть это свойство конфигурации надо до публикации.
Авторизация и права
Клиент ходит с заголовком Authorization и логином-паролем в base64. Пользователю нужна либо роль «Полные права», либо специальная роль УдаленныйДоступOData — её документация 1С:Фреш называет по имени и говорит, что служебному пользователю она назначается автоматически при создании через типовую обработку настройки. Под интеграцию лучше и заводить отдельного служебного пользователя, потому что по нему видно, кто именно вытянул данные, и права режутся независимо от живых сотрудников. Если по этому интерфейсу в базу пойдёт не скрипт выгрузки, а ИИ-агент через MCP-сервер, права служебного пользователя перестают быть формальностью и становятся единственной границей — что при этом видит агент и как её ставить, разобрано отдельно: MCP для 1С и права доступа.
Здесь права 1С применяются в полном объёме. Если у служебного пользователя нет доступа к документам, состав интерфейса он увидит, а данные — по своим правам. При действующих ограничениях доступа на уровне записей запрос возвращает 401, пока в него не добавлен параметр allowedOnly=true; с этим параметром в ответ попадают только записи, не попавшие под ограничение. Без него интеграция выглядит как проблема с паролем, хотя дело в RLS.
Устройство запроса
Для внешней системы это выглядит как обычный REST API поверх базы 1С. GET по адресу ресурса возвращает ответ в Atom/XML либо в JSON, второе включается параметром $format=json или заголовком Accept: application/json. Запись тоже работает — POST, PATCH и DELETE. Если важно не затереть чужую правку, при чтении надо забрать DataVersion и передать его в заголовке If-Match, тогда изменившуюся с момента чтения запись сервер отклонит; без If-Match проверки версии не будет и запись перезапишется молча. При записи платформа выполняет проверки прав и вызывает обработчики событий, так что внешний запрос проходит тот же путь, что и правка руками в интерфейсе.
Об одну вещь в этом ряду спотыкаются ровно один раз. DELETE через OData убирает объект сразу, без пометки на удаление; привычной «корзины» здесь нет. Успешное удаление отвечает пустым 204, так что и подтверждения в ответе не будет. Право удаления у служебного пользователя стоит отбирать раньше, чем начнётся отладка клиента.
Из общего списка выбиваются планы обмена. Формально они доступны, но фирма «1С» прямо не рекомендует их открывать, потому что некорректная запись в план обмена ломает приложение. Виртуальные таблицы регистров тоже доступны, но не через URL сущности.
Первый запрос после публикации — $metadata. По адресу /odata/standard.odata/$metadata платформа отдаёт XML-описание всего, что реально открыто, вплоть до имён полей и доступных функций. Это же и способ проверить состав интерфейса, не гадая по ошибкам. Никаких параметров этот адрес не принимает, $format в том числе, — ответ приходит только в XML.
Имя ресурса состоит из типа объекта и его имени в метаданных — Catalog_Контрагенты, Document_ПоступлениеТоваров, InformationRegister_ЦеныНоменклатуры. Одиночный элемент адресуют идентификатором в скобках — Catalog_Контрагенты(guid'…'), — и это отдельная форма запроса, у которой свои ограничения. Дальше идут обычные параметры OData.
| Параметр | Что делает | На что обратить внимание |
|---|---|---|
| $filter | отбирает записи по условию | даты — литералом datetime'…', ссылки — guid'…', условия через and и or |
| $select | перечисляет нужные поля через запятую | без него объект приезжает целиком, со всеми реквизитами |
| $top, $skip | ограничивают выборку и пропускают начало | пара, на которой держится постраничный обход |
| $orderby | задаёт порядок записей | без него порядок не гарантирован, и постраничный обход поедет |
| $count, $inlinecount | считают записи | $count отдаёт только число, $inlinecount=allpages добавляет его к выборке |
| $expand | подтягивает связанные сущности одним запросом | работает не везде, ограничения — ниже |
| $format=json | переключает ответ с atom-xml на JSON | то же делает заголовок Accept: application/json |
| allowedOnly=true | оставляет только разрешённые правами записи | без него запрос при действующих RLS завершится ошибкой 401 |
Что умеет отбор
Расхожее представление о $filter — «равно и больше-меньше, остальное на принимающей стороне». Начиная с 8.3.8 это не так. Платформа поддерживает стандартные функции OData для строк (substring, substringof, startswith, endswith, concat), для дат (year, month, day, hour, minute, second) и приведение типов (isof, cast, round). Сверх стандарта фирма «1С» добавила свои — like, datedifference, dateadd, quarter, dayofweek, dayofyear. Половина ночных выгрузок «всё, а потом отфильтруем у себя» существует по незнанию этого списка.
Отдельно стоят два оператора по табличным частям — any и all. Они отбирают документы по содержимому строк, например все расходные документы, где хоть в одной строке цена превысила порог. Без них такой отбор превращается в выгрузку всех документов вместе со строками. Составные типы отбирают через cast с указанием целевой сущности, иначе сравнение ссылки с элементом справочника не строится.
Операции сравнения по реквизиту типа «ХранилищеЗначения» платформа не поддерживает — ни в $filter, ни в $orderby. В ответе на такой запрос причина названа не будет, поэтому реквизит этого типа стоит опознавать заранее, по $metadata.
Весь этот набор собирался три года, и примеры из интернета молча предполагают свежую платформу. На 8.3.5 половина из них не сработает, причём без внятной диагностики: на неподдерживаемый параметр платформа отвечает ошибкой запроса, и по ответу версия никак не угадывается. Таблица ниже показывает, в какой версии что появилось.
| Версия | Что появилось |
|---|---|
| 8.3.5 | сам механизм, OData 3.0, ответ только в atom-xml, атрибут enableStandardOData в default.vrd, метод установки состава |
| 8.3.6 | ответ в JSON, ускорение обработки запросов, из документации убрана функция mod |
| 8.3.7 | независимый регистр сведений без измерений, свойство SurrogateKey |
| 8.3.8 | $skip, $orderby, $count, $inlinecount, строковые и датные функции отбора, any и all по табличным частям, cast по составным типам |
Чего 1С по OData не отдаёт
- Отчёты и обработки наружу не уходят. Попросить «дай отчёт по продажам за квартал» через OData не получится: агрегацию делает принимающая сторона.
- Команды и критерии отбора закрыты, логику конфигурации снаружи не дёрнуть.
- Регламентные задания недоступны, запустить обмен или пересчёт по расписанию извне нельзя.
- Пользователей информационной базы интерфейс не публикует.
- Внешние источники данных дальше не транслируются. То, что 1С сама читает снаружи, остаётся внутри.
- Журнал регистрации: в перечне доступных объектов его нет, отдельного ресурса под него не появляется.
Первые пять пунктов — не наблюдение практиков, а перечисление из блога фирмы «1С», которым механизм и представляли. Ни в одном просмотренном нами документе изменений платформы после 8.3.5 эти объекты в доступные не переводили.
Два вызова, которые проводят документ
Формула «OData отдаёт данные, а действия — это уже свой HTTP-сервис» верна не целиком. Через интерфейс вызывают и методы самих объектов. Документ проводят и распроводят вызовом Post() и Unpost() по адресу конкретного документа, задачу выполняют через ExecuteTask(), бизнес-процесс стартует через Start(). Технически это POST на адрес вида Document_РеализацияТоваров(guid'…')/Post().
Из этого следуют две вещи сразу. Внешняя система может провести документ, который сама же и создала, — сценарий «залить заказы из интернет-магазина и провести» закрывается штатным механизмом целиком. И ровно поэтому право проведения у служебного пользователя надо отбирать осознанно: снаружи оно выглядит таким же безобидным POST-запросом, как создание элемента справочника. Отказ приложения проводить документ приезжает пустым ответом 500, без объяснения причины.
Виртуальные таблицы регистров и их функции
Виртуальные таблицы регистров через обычный URL сущности не читаются. Вместо них платформа даёт функции, у каждой свой набор именованных параметров, и параметры эти уходят прямо в адресе. Остатки по номенклатуре и местам хранения помещаются в один такой адрес: /odata/standard.odata/AccumulationRegister_ТоварныеЗапасы/Balance(Period=datetime'2026-02-01T00:00:00',Dimensions='Номенклатура')?$format=json.
| Вид регистра | Функции | Параметры |
|---|---|---|
| накопления | Balance() | Period, Dimensions, Condition |
| накопления | Turnovers(), BalanceAndTurnovers() | StartPeriod, EndPeriod, Dimensions, Condition |
| бухгалтерии | Balance(), Turnovers(), BalanceAndTurnovers(), ExtDimensions(), RecordsWithExtDimensions(), DrCrTurnover() | в документации не описаны |
| сведений (периодический) | SliceLast(), SliceFirst() | Period, Condition |
| расчёта | ScheduleData(), ActualActionPeriod() | зависят от регистра |
Обратите внимание на строку про регистры бухгалтерии. Функций у них больше: субконто отдают ExtDimensions() и RecordsWithExtDimensions(), обороты по корреспонденции DrCrTurnover(). Но набор именованных параметров для них в документации не расписан, в отличие от регистров накопления. Переносить туда сигнатуру Balance(Period, Dimensions, Condition) по аналогии не стоит: проверяйте на своей публикации.
У функций оборотов нет параметра периодичности: разбить обороты по месяцам одним запросом, как в языке запросов 1С, здесь нечем. Точные имена и параметры под свою конфигурацию всё равно надёжнее взять из $metadata своей публикации — он отдаёт их за один GET и не расходится с версией платформы.
Тот, кто ждал от OData языка запросов 1С, обнаружит здесь потолок. Соединить два регистра одним запросом нельзя, посчитать произвольный итог нельзя. Есть фиксированный набор функций и фильтрация поверх результата.
Где это ломается
Первым упирается $expand. Ограничений у него три, и все три описаны: расширение недоступно для реквизитов табличных частей, недоступно при запросе одиночных сущностей, а расширение ссылочных и составных типов виртуальных таблиц не соответствует протоколу OData третьей версии. Практический смысл одинаковый: вместо одного запроса получается обход строк по одной. Отсюда же требование к объёму — постраничный обход через $top и $skip нужен с первого дня, иначе большая таблица упирается в таймаут веб-сервера, а не в лимит OData.
По коду ответа не всегда понятно, дело в правах, в составе интерфейса или в неподдерживаемом типе: ошибки платформа описывает общо. Опечатка в имени параметра — $expan вместо $expand — даёт ответ «параметр не поддерживается», то есть ту же формулировку, что и настоящее ограничение платформы.
Выдержит ли рабочая база выгрузку
Дальше начинается то, что к OData отношения уже не имеет. Тяжёлая выборка — это обычный сеанс в той же базе, где работают люди, и конкурирует он за те же ресурсы; ночное окно или копия базы под выгрузку здесь не перестраховка. Типовая установка стоит в локальной сети без внешнего адреса, и опубликовать интерфейс мало, до него ещё надо дотянуться. Из веб-страницы напрямую тоже обычно не выходит, потому что CORS-заголовки штатно не приходят; на практике их добавляют на веб-сервере, через customHeaders в web.config для IIS.
Три способа отдать данные наружу
| OData | HTTP-сервис | Прямой SQL | |
|---|---|---|---|
| Сколько кода писать | нисколько | свой обработчик на каждый метод | запросы к таблицам СУБД |
| Что можно отдать | данные объектов и вызов их методов | любой результат, включая отчёт | всё, что лежит в базе |
| Преагрегация на стороне 1С | нет | да | нет |
| Права 1С | применяются, состав интерфейса ограничивает сверху | применяются к пользователю, под которым идёт вызов, но что отдать — решает код обработчика | обходятся: роли и RLS проверяет платформа, а не сервер СУБД |
| Поддержка фирмой «1С» | штатный механизм | штатный механизм | не поддерживается |
Своё видится удобным ровно там, где OData упирается: нужен один запрос вместо ста, нужна агрегация до отправки, нужен свой формат ответа. За это платят кодом, который придётся сопровождать при каждом обновлении конфигурации. Прямое чтение таблиц СУБД быстрее, но не поддерживается фирмой «1С», потому что имена таблиц не документированы и меняются между релизами платформы. Сам код клиента при любом из трёх вариантов кто-то пишет и сопровождает — здесь помогает работа с конфигурацией выгруженной в файлы, в обычном редакторе с ИИ-агентом. Отдельно стоит помнить, что прямой SQL проходит мимо ролей и RLS: то, что через OData закрыто ролью, из СУБД читается целиком.
Работает ли это в 1С:Фреш
В облачном сервисе прикладные базы уже опубликованы с включённым интерфейсом OData, и настраивать веб-сервер не нужно. Это самый лёгкий вход в тему, для первой пробы хватает логина, пароля и адреса приложения.
Заголовок 1C_OData-DataLoadMode: true, который в коробочной версии переводит запись в режим загрузки данных, во Фреше не поддерживается. Запросы с ним не обрабатываются.
Клиент к OData всё равно пишется руками — постраничный обход, повторные попытки, разбор ошибок, маппинг типов 1С в типы принимающей системы. WorkAI — полноценная IDE с ИИ-агентом внутри. Агент видит проект целиком, пишет такой клиент и правит его по замечаниям. Открытые модели работают бесплатно постоянно, без карты и без ограничения по времени.
Скачать WorkAI IDE — бесплатноЧастые вопросы
Можно ли отдать наружу не весь справочник, а только часть его реквизитов?
Составом — нет. Состав стандартного интерфейса работает по объектам метаданных целиком: объект либо в нём есть, либо его нет, промежуточного положения «есть, но без паспортных данных» интерфейс не предусматривает. $select тут не помогает: набор полей выбирает клиент, и ничто не мешает ему запросить объект без $select и получить все реквизиты. Реальный рычаг один — роль служебного пользователя со снятым правом чтения нужных реквизитов, при необходимости вместе с ограничением на уровне записей. Права платформа проверяет на каждом обращении, состав интерфейса — только на входе.
Что ломается в интеграции по OData после обновления конфигурации?
Имена ресурсов интерфейс собирает из имён объектов и реквизитов в метаданных, поэтому переименование реквизита при доработке меняет и адрес, и структуру ответа. Клиент об этом узнаёт не сообщением «поле переименовано», а обычной ошибкой запроса — той же по формулировке, что и опечатка в параметре. Состав при этом задаётся явно, поэтому появившиеся при доработке объекты сами в него не попадут — их придётся вносить отдельно. Практический приём здесь один и дешёвый — сохранять ответ $metadata до обновления и сравнивать с ним после, тогда расхождение видно списком, а не по упавшему ночному обмену.
Подойдёт ли OData для регулярной выгрузки данных из 1С в хранилище?
Для умеренных объёмов да, при постраничном обходе и с оглядкой на нагрузку на рабочую базу. Клиент к такой выгрузке — обычная программа, и её пишут теми же приёмами, что и любой другой код, вплоть до агентного цикла с автозапуском тестов. Для больших таблиц с полной перезагрузкой каждую ночь механизм становится узким местом, и выгрузку обычно переводят на инкрементальную, по дате изменения или по регистру-накопителю.
Занимают ли OData-запросы клиентские лицензии?
Сам механизм веб- и HTTP-сервисов клиентскую лицензию не запрашивает. В своём FAQ по лицензированию (разд. IX) фирма «1С» отвечает прямо, что веб-сервисы отдельно не лицензируются, но каждое рабочее место, с которого любым способом идёт доступ к данным информационной базы, должно быть обеспечено клиентской лицензией. Перед промышленной интеграцией это вопрос к поставщику лицензий.