При разработке интеграций через HTTP-сервисы в системе 1С:Предприятие программисты часто сталкиваются с дилеммой: какой код состояния (Status Code) вернуть клиенту, если данных нет или произошла ошибка. Использование стандартного кода 200 OK для всех ситуаций упрощает разработку, но нарушает общепринятые стандарты REST API. С другой стороны, использование кодов ошибок (4xx, 5xx) в 1С может сопровождаться трудностями при передаче описания проблемы. В этой статье мы подробно разберем, как правильно проектировать ответы ваших сервисов.
Рассмотрим ситуацию: клиент запрашивает список заказов по определенному контрагенту, но заказов в базе нет. Какой код должен вернуть сервер? Проанализируем три основных варианта:
[] в JSON). Это не является ошибкой сервера или отсутствием ресурса.PUT или POST, когда клиенту не нужно подтверждение в виде обновленного объекта. Использовать его для GET-запросов на получение данных не рекомендуется, так как многие библиотеки-клиенты могут интерпретировать отсутствие тела как технический сбой./orders/123 и заказа 123 не существует — это 404. Но если вы обратились к /orders?client=123 и список пуст — это 200.Часто разработчики замечают, что при установке кода, отличного от 200, метод УстановитьТелоИзСтроки() в объекте HTTPСервисОтвет как будто игнорируется, и клиент получает стандартную страницу ошибки веб-сервера. Разберем, почему так происходит.
Выясним причину: в большинстве случаев виноват не код в 1С, а настройки веб-сервера (IIS или Apache), на котором опубликован сервис. Веб-серверы по умолчанию перехватывают ответы с кодами 4xx и 5xx, заменяя ваше информативное JSON-описание своей стандартной разметкой (Custom Errors).
Для решения этой проблемы в IIS: необходимо в файле web.config вашего приложения установить параметр existingResponse="PassThrough". Это заставит IIS пропускать ответ от 1С "как есть", сохраняя ваше тело сообщения.
Также важно помнить: свойство Причина (Reason Phrase) в ответе — это устаревающая практика. В протоколе HTTP/2 текст причины вообще не передается. Всю информацию об ошибке нужно помещать именно в тело ответа в формате JSON.
Вместо того чтобы изобретать свой формат передачи ошибок, проанализируем стандарт RFC 7807 (Problem Details for HTTP APIs). Согласно ему, при возникновении ошибки (например, 400 Bad Request), сервер должен вернуть JSON со структурой, понятной любому разработчику:
type: Ссылка на документацию с описанием типа ошибки.title: Краткий, понятный человеку заголовок.status: Код HTTP (дублируется для удобства парсинга).detail: Подробное описание того, что именно пошло не так.Рассмотрим пример формирования такого ответа на стороне 1С:
Ответ = Новый HTTPСервисОтвет(400);
ДанныеОшибки = Новый Структура;
ДанныеОшибки.Вставить("status", 400);
ДанныеОшибки.Вставить("title", "Ошибка валидации данных");
ДанныеОшибки.Вставить("detail", "Поле 'ИНН' должно содержать 10 или 12 цифр.");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеОшибки);
СтрокаJSON = ЗаписьJSON.Закрыть();
Ответ.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Ответ.Заголовки.Вставить("Content-Type", "application/problem+json");
Возврат Ответ;
Когда вы вызываете внешний сервис из 1С с помощью объекта HTTPСоединение, важно правильно обработать результат. По умолчанию методы типа ВызватьHTTPМетод() или Получить() могут вызывать исключение при кодах 4xx и 5xx, если не настроены определенные параметры.
Рассмотрим правильную схему обработки ответа на стороне клиента:
Попытка
Ответ = Соединение.ВызватьHTTPМетод("GET", "api/v1/resource");
Если Ответ.КодСостояния = 200 Тогда
// Обрабатываем успешные данные
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Результат = ПрочитатьJSON(ЧтениеJSON);
ИначеЕсли Ответ.КодСостояния = 404 Тогда
Сообщить("Объект не найден в базе источника");
Иначе
// Обрабатываем бизнес-ошибку из тела ответа
ТелоОшибки = Ответ.ПолучитьТелоКакСтроку();
Сообщить("Сервер вернул ошибку: " + ТелоОшибки);
КонецЕсли;
Исключение
// Сюда мы попадем при сетевых ошибках или таймаутах
Сообщить("Ошибка связи: " + ОписаниеОшибки());
КонецПопытки;
В обсуждениях иногда всплывают коды с точкой, например 404.1. Важно понимать: в протоколе HTTP таких кодов не существует. Это внутренние подкоды веб-сервера IIS, которые он использует для своих логов. По сети клиенту всегда уходит только основной трехзначный код. Если вам нужно передать специфический код бизнес-ошибки (например, "Ошибка №15: Недостаточно остатка на складе"), передавайте его внутри JSON-тела, оставляя HTTP-код на уровне общей категории 400 Bad Request или 422 Unprocessable Entity.
Подведем итог наших изысканий по работе с HTTP в 1С:
200 OK и пустой массив [].404 Not Found.400 Bad Request.Следуя этим правилам, вы сделаете свои интеграции предсказуемыми, надежными и соответствующими мировым стандартам разработки ПО.