Стандартный REST-доступ к базе 1С 8.3 через OData: публикация, запросы, JSON и права
Содержание
Интерфейс OData в 1С — это встроенный в платформу REST-доступ к данным базы: справочникам, документам, регистрам и константам. Чтобы подключить его, нужно опубликовать базу на веб-сервере с флажком «Публиковать стандартный интерфейс OData», а затем указать, какие объекты открыть наружу. После этого внешняя система читает и пишет данные обычными HTTP-запросами по адресу вида http://сервер/база/odata/standard.odata/.
Программировать на стороне 1С ничего не нужно: ни веб-сервисов, ни HTTP-сервисов, ни обработок обмена. Интерфейс появился в платформе 8.3.5 и работает одинаково в любой конфигурации — Бухгалтерии, ЗУП, УТ, ERP или самописной. Отличается только способ выбрать состав объектов, о нём ниже.
Что даёт стандартный интерфейс OData и когда он уместен
OData (Open Data Protocol) — открытый протокол поверх HTTP. Каждая таблица базы становится «сущностью» со своим адресом, а запись — ресурсом, который можно получить, создать, изменить или удалить. Платформа 1С реализует протокол OData версии 3.0 и отдаёт данные в форматах Atom/XML и JSON.
Где OData в 1С удобен:
- 📊 выгрузка в BI-системы — Power BI, Excel (Power Query) и другие инструменты умеют подключаться к источнику OData без программирования;
- 🔗 интеграция с сайтом или CRM — внешний сервис забирает номенклатуру, остатки, цены, статусы заказов;
- 📱 мобильные и веб-приложения — читают справочники и создают документы напрямую;
- 🧪 разовые выборки — аналитик получает данные запросом из браузера или Postman, не открывая 1С.
Когда лучше выбрать другой путь:
| Задача | Чем решать | Почему |
|---|---|---|
| Стандартное чтение и запись объектов | OData | Готово «из коробки», без кода |
| Нестандартная логика, расчёт на сервере, своя структура ответа | HTTP-сервис в конфигурации | Полный контроль над запросом и ответом |
| Обмен по жёсткому контракту (WSDL) с госсистемой или банком | SOAP веб-сервис | Требование второй стороны |
| Синхронизация двух баз 1С | Планы обмена, «Конвертация данных» | Регистрация изменений, коллизии, правила |
OData отдаёт данные «как они лежат в таблицах». Бизнес-логику конфигурации он не повторяет: например, при создании документа через OData не сработает заполнение реквизитов, которое выполняет форма. Обработчики модуля объекта (ПередЗаписью, ОбработкаПроведения) при этом выполняются.
Как устроен обмен: адреса сущностей и HTTP-методы
Все обращения идут к одной точке входа — odata/standard.odata внутри публикации. Описание всех доступных сущностей лежит по адресу .../standard.odata/$metadata: с него начинают знакомство с интерфейсом.
Как называются объекты базы
Имя сущности складывается из типа объекта на английском и его имени в конфигурации:
| Объект 1С | Имя сущности в OData |
|---|---|
| Справочник «Контрагенты» | Catalog_Контрагенты |
| Документ «Реализация товаров и услуг» | Document_РеализацияТоваровУслуг |
| Табличная часть «Товары» документа | Document_РеализацияТоваровУслуг_Товары |
| Регистр сведений | InformationRegister_ИмяРегистра |
| Регистр накопления (записи) | AccumulationRegister_ИмяРегистра_RecordType |
| План счетов | ChartOfAccounts_Хозрасчетный |
| Константа | Constant_ИмяКонстанты |
Конкретная запись адресуется по уникальному идентификатору ссылки:
Catalog_Контрагенты(guid'6b3f1e2a-0c1d-11ee-8a4b-005056a1b2c3')
Ссылочные реквизиты в ответе приходят с суффиксом _Key — например, Контрагент_Key содержит GUID контрагента, а не его наименование.
Какие HTTP-методы поддерживаются
| Метод | Что делает | Пример |
|---|---|---|
| GET | Читает список или одну запись | GET Catalog_Номенклатура |
| POST | Создаёт новую запись | POST Catalog_Контрагенты с телом JSON |
| PATCH | Меняет отдельные поля записи | PATCH Catalog_Контрагенты(guid'...') |
| DELETE | Физически удаляет запись | DELETE Document_...(guid'...') |
Для документов есть ещё два действия — проведение и отмена проведения. Это POST-запросы к записи с суффиксом /Post() и /Unpost().
DELETE в OData удаляет объект сразу, без пометки и без контроля ссылок. Чтобы поступить как пользователь в 1С, отправьте PATCH с полем "DeletionMark": true, а удаление помеченных выполните штатной обработкой.
Публикация базы и включение OData по шагам
Ниже — порядок для веб-сервера Apache или IIS на той же машине, где установлена платформа. Для публикации нужны права администратора Windows и установленный компонент «Модули расширения веб-сервера».
Шаг 1. Опубликовать базу с флажком OData
- Запустите Конфигуратор от имени администратора Windows.
- Откройте меню
Администрирование → Публикация на веб-сервере. - Укажите имя публикации латиницей, например
buh, выберите веб-сервер и каталог. - Включите флажок «Публиковать стандартный интерфейс OData».
- Нажмите «Опубликовать» и подтвердите перезапуск веб-сервера.
Для Linux и консольной публикации есть утилита webinst. После публикации в каталоге появится файл default.vrd, а в нём — элемент <standardOdata enable="true" .../>. Если флажок забыт, достаточно переопубликовать базу.
Перезапуск Apache или IIS обрывает текущие веб-сеансы: тонкий клиент через браузер, другие HTTP- и веб-сервисы этой публикации. Делайте это вне рабочего времени или предупредите пользователей.
Шаг 2. Выбрать состав объектов
Сразу после публикации запрос к $metadata вернёт почти пустой список. Это нормально: по умолчанию платформа ничего не открывает. Состав задают одним из трёх способов.
| Способ | Где | Для каких конфигураций |
|---|---|---|
| Встроенная настройка БСП | Администрирование → Синхронизация данных, ссылка «Настройка стандартного интерфейса OData» | Типовые на БСП: БП 3.0, ЗУП 3.1, УТ 11, КА, ERP |
| Внешняя обработка настройки OData | Открывается через Файл → Открыть в пользовательском режиме | Конфигурации без встроенной настройки |
| Код на встроенном языке | Метод УстановитьСоставСтандартногоИнтерфейсаOData() | Самописные и доработанные базы |
Во встроенной настройке БСП открытие объектов связано с созданием отдельного пользователя для OData: программа предложит задать ему имя и пароль, а после отметки объектов сама выдаст нужные права. Работать под этой учётной записью в 1С нельзя — она только для внешнего доступа.
Пример программной настройки, который выполняют один раз в привилегированном режиме:
Состав = Новый Массив;
Состав.Добавить(Метаданные.Справочники.Номенклатура);
Состав.Добавить(Метаданные.Справочники.Контрагенты);
Состав.Добавить(Метаданные.Документы.ЗаказКлиента);
УстановитьСоставСтандартногоИнтерфейсаOData(Состав);
Метод заменяет состав целиком, а не дополняет его. Чтобы добавить объект к уже открытым, сначала получите текущий список методом ПолучитьСоставСтандартногоИнтерфейсаOData(), добавьте в него новые элементы и передайте обратно.
💡 Открывайте вместе с документом его табличные части и справочники, на которые он ссылается. Иначе ссылки _Key нельзя будет «развернуть» в читаемые наименования.
Шаг 3. Проверить в браузере
Откройте адрес:
http://localhost/buh/odata/standard.odata/$metadata
Браузер спросит логин и пароль пользователя 1С. Если в ответе XML со списком EntityType — интерфейс работает. Затем проверьте реальные данные:
http://localhost/buh/odata/standard.odata/Catalog_Номенклатура?$top=5&$format=json
Запросы с фильтрами: $filter, $select, $expand и другие
Параметры запроса пишутся после ? и соединяются знаком &. Без них сервер отдаст все записи и все поля — на крупной базе это минуты ожидания и сотни мегабайт.
| Параметр | Назначение | Пример |
|---|---|---|
$select | Только нужные поля | $select=Ref_Key,Description,Артикул |
$filter | Условие отбора | $filter=DeletionMark eq false |
$top / $skip | Порция и смещение | $top=100&$skip=200 |
$orderby | Сортировка | $orderby=Date desc |
$expand | Подтянуть связанный объект | $expand=Контрагент |
$inlinecount | Общее число записей | $inlinecount=allpages |
$format | Формат ответа | $format=json |
allowedOnly | Только разрешённые записи (RLS) | allowedOnly=true |
Операторы и примеры условий
В $filter работают операторы сравнения eq, ne, gt, ge, lt, le, логические and, or, not и строковые функции вроде substringof и startswith.
Проведённые реализации за январь:
Document_РеализацияТоваровУслуг?$filter=Posted eq true and Date ge datetime'2025-01-01T00:00:00' and Date lt datetime'2025-02-01T00:00:00'&$select=Ref_Key,Number,Date,СуммаДокумента&$format=json
Контрагенты, в наименовании которых есть «Ромашка»:
Catalog_Контрагенты?$filter=substringof('Ромашка', Description)&$format=json
Отбор по ссылке — через поле _Key и GUID:
Document_ЗаказКлиента?$filter=Контрагент_Key eq guid'6b3f1e2a-0c1d-11ee-8a4b-005056a1b2c3'
Имена стандартных реквизитов — английские: Ref_Key, Description, Code, Number, Date, Posted, DeletionMark, Parent_Key. Свои реквизиты называются так же, как в конфигурации, по-русски.
Виртуальные таблицы регистров
Остатки и срез последних тоже доступны — это функции, которые вызываются от сущности регистра:
- 📦
AccumulationRegister_ТоварыНаСкладах/Balance(Period=datetime'2025-03-31T23:59:59')— остатки на дату; - 🔄
AccumulationRegister_.../Turnovers()— обороты; - 💰
InformationRegister_ЦеныНоменклатуры/SliceLast()— последние цены.
Регистр обязательно должен входить в состав интерфейса. Названия регистров смотрите в $metadata: в разных конфигурациях они отличаются.
Кириллицу и пробелы в адресе браузер кодирует сам. В коде внешней системы используйте функцию URL-кодирования своего языка, иначе сервер вернёт ошибку разбора запроса.
Ответ в JSON и запись данных обратно в 1С
С параметром $format=json или заголовком Accept: application/json сервер возвращает JSON. Список записей лежит в массиве value:
{
"odata.metadata": "http://localhost/buh/odata/standard.odata/$metadata#Catalog_Номенклатура",
"value": [
{
"Ref_Key": "1f2e3d4c-0000-11ee-8a4b-005056a1b2c3",
"Description": "Бумага А4",
"Артикул": "BA4-500",
"DeletionMark": false
}
]
}
Что учитывать при разборе ответа:
- 🗓️ даты приходят строкой в формате
2025-01-15T10:30:00, без часового пояса — это время сервера 1С; - 🔑 пустая ссылка — нулевой GUID
00000000-0000-0000-0000-000000000000, а неnull; - 🧾 табличная часть приходит массивом внутри документа, если её не отрезали через
$select; - 🔢 числа — без разделителей разрядов, дробная часть через точку.
Создание записи
Новый контрагент создаётся POST-запросом к сущности, тело — JSON с полями:
POST /buh/odata/standard.odata/Catalog_Контрагенты?$format=json
Content-Type: application/json
Authorization: Basic <логин:пароль в Base64>
{
"Description": "ООО Ромашка",
"ИНН": "7701234567"
}
В ответ сервер вернёт созданную запись вместе с её Ref_Key. Сохраните этот GUID у себя: по нему потом обновляют запись.
Изменение и проведение документа
Чтобы поменять одно поле, отправьте PATCH только с ним. Остальные реквизиты останутся прежними. Документ проводится отдельным запросом:
POST /buh/odata/standard.odata/Document_ЗаказКлиента(guid'...')/Post()
Если проведение не прошло — например, не хватило остатков, — сервер вернёт ошибку с текстом сообщения из модуля проведения. Записывать при этом ничего не придётся: документ останется непроведённым.
Тестируйте запись через OData на копии базы. Ошибка в цикле внешней системы за минуту создаст сотни лишних документов, а массовый DELETE не оставит даже пометок на удаление.
Авторизация и защита публикации
Стандартный интерфейс OData использует обычную аутентификацию 1С по логину и паролю пользователя информационной базы. Внешняя система передаёт их в заголовке Authorization: Basic. Логин и пароль кодируются в Base64 — это не шифрование, поэтому:
- 🔒 Публикуйте наружу только по HTTPS. Сертификат настраивается на веб-сервере, 1С тут ничего не делает. Без HTTPS пароль виден любому, кто перехватит трафик.
- 👤 Создайте отдельного пользователя под интеграцию. Не отдавайте учётку бухгалтера или администратора: при увольнении сотрудника интеграция сломается, а в журнале регистрации не разобрать, кто что менял.
- 📉 Дайте минимум прав. Только чтение — если внешней системе нужно только читать. Права на изменение — только на те объекты, которые она реально пишет.
- 🧱 Сузьте состав интерфейса. Объект, которого нет в составе, через OData недоступен вообще, даже при полных правах пользователя.
- 🌐 Ограничьте доступ по сети. Белый список IP-адресов на веб-сервере или файрволе закрывает публикацию от сканеров.
Если в базе настроено ограничение доступа на уровне записей (RLS), запрос без параметра allowedOnly=true может завершиться ошибкой при попытке прочитать запрещённые записи. С этим параметром сервер просто их отфильтрует.
Ошибки подключения: по коду ответа к причине
Ответ сервера с ошибкой содержит код HTTP и, как правило, текст на русском в теле. Начинайте разбор с кода.
Ещё две частые проблемы без явного кода ошибки:
- ⏳ Запрос «висит» минутами. Чаще всего не задан
$selectи$top, и сервер собирает всю таблицу со всеми табличными частями. Читайте порциями по 500–1000 записей. - 🧩 Поле есть в 1С, но нет в ответе. После доработки конфигурации состав интерфейса не обновился. Переоткройте настройку OData и сохраните её заново или повторите вызов
УстановитьСоставСтандартногоИнтерфейсаOData().