При работе со стандартным REST-интерфейсом OData в 1С:Предприятии часто возникает необходимость найти и обновить конкретную запись по значению реквизита (например, по коду, артикулу или ИНН). Попытка отправить модифицирующий HTTP-запрос (PATCH или PUT) с параметрами фильтрации $filter напрямую на URL коллекции приводит к ошибке с кодом 19: "Использованный HTTP метод запрещен в данном контексте" (HTTP status 405).
Проанализируем архитектурные ограничения платформы 1С и разберем практические способы решения этой задачи.
Выясним, почему платформа не позволяет модифицировать данные по фильтру за один HTTP-вызов:
PATCH, PUT, DELETE) адресовались строго конкретному экземпляру сущности по его каноническому URL. Для справочников и документов этот адрес обязательно содержит первичный ключ — уникальный идентификатор guid'...'.$filter, $top и $orderby предназначены только для операций чтения (GET) над коллекциями сущностей. Маршрутизатор 1С блокирует попытки передачи методов изменения на адрес всей коллекции.Если информационная база находится на типовой поддержке и её нельзя модифицировать, единственным штатным решением является последовательное выполнение двух HTTP-запросов. Чтобы свести к минимуму нагрузку на веб-сервер и СУБД, проанализируем, как правильно оптимизировать первый запрос чтения.
Шаг 1. Легковесный GET-запрос для получения GUID:
Запрашиваем исключительно ключ ссылки Ref_Key, передавая фильтр и ограничение на количество записей. Вызов параметра $select=Ref_Key предписывает платформе считывать только идентификатор объекта, игнорируя остальные реквизиты и табличные части.
Пример HTTP GET-запроса:
GET /base/odata/standard.odata/Catalog_Контрагенты?$filter=Code eq '000000001'&$select=Ref_Key&$top=1&$format=json
В ответе от сервера получаем структуры с нужным GUID:
{
"odata.metadata": "http://server/base/odata/standard.odata/$metadata#Catalog_Контрагенты/$entity",
"Ref_Key": "e1c8e182-1234-11e8-80c7-005056c00008"
}
Шаг 2. Модификация объекта через PATCH:
Используя полученный Ref_Key, формируем канонический URL элемента и отправляем запрос на частичное изменение данных.
Пример HTTP PATCH-запроса:
PATCH /base/odata/standard.odata/Catalog_Контрагенты(guid'e1c8e182-1234-11e8-80c7-005056c00008')?$format=json
В теле запроса передаем только те свойства, которые необходимо обновить:
{
"Комментарий": "Обновлено через REST API"
}
Если условием интеграции является выполнение операции строго за один HTTP-запрос, оптимальным решением станет разработка собственного HTTP-сервиса. Чтобы не снимать конфигурацию с поддержки, создадим расширение конфигурации.
Рассмотрим порядок действий при таком подходе:
ОбновлениеОбъектов) с корневым URL /update./by-code и метод POST (или PATCH) с обработчиком в модуле HTTP-сервиса.Пример кода обработчика HTTP-запроса в 1С:
Функция ПостПоискаИОбновления(Запрос)
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Запрос.ПолучитьТелоКакСтроку());
ДанныеЗапроса = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
КодОбъекта = ДанныеЗапроса.Код;
НовыйКомментарий = ДанныеЗапроса.Комментарий;
// Поиск объекта в базе данных
СсылкаНаОбъект = Справочники.Контрагенты.НайтиПоКоду(КодОбъекта);
Если СсылкаНаОбъект.Пустая() Тогда
Ответ = Новый HTTPСервисОтвет(404);
Возврат Ответ;
КонецЕсли;
// Обновление реквизитов объекта
Попытка
ОбъектБД = СсылкаНаОбъект.ПолучитьОбъект();
ОбъектБД.Комментарий = НовыйКомментарий;
ОбъектБД.Записать();
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки("Text updated successfully");
Исключение
Ответ = Новый HTTPСервисОтвет(500);
Ответ.УстановитьТелоИзСтроки(ОписаниеОшибки());
КонецПопытки;
Возврат Ответ;
КонецФункции
В результате внешний клиент сможет отправить ровно один HTTP-запрос на адрес собственного сервиса и обновить данные объекта без знания его Ref_Key.
Обратим внимание на работу с регистрами сведений. В отличие от справочников и документов, записи независимых или периодических регистров сведений не имеют ссылок типа GUID. В OData канонический URL записи регистра формируется из значений ключевых измерений и даты периода.
В этом случае знание GUID не требуется — обновлять или записывать данные через PUT/PATCH можно сразу за один запрос, если известны значения всех ключевых полей измерения:
PUT /base/odata/standard.odata/InformationRegister_ЦеныНоменклатуры(Period=datetime'2023-01-01T00:00:00', Номенклатура_Key=guid'...')