Как передать параметры в формате JSON в HTTP-запросе в 1С: решаем проблему на примере ServiceDesk Plus API v3

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Интеграция 1С с внешними информационными системами через веб-службы (REST API) стала повседневной задачей для современного разработчика. Одним из наиболее популярных стандартов обмена данными сегодня является формат JSON. Однако при реализации взаимодействия часто возникают технические трудности, связанные с тем, как именно передавать эти данные в HTTP-запросах. Особенно много вопросов вызывают GET-запросы со сложными фильтрами.

В этой статье мы детально разберем проблему, с которой сталкиваются разработчики при интеграции 1С с популярной системой ServiceDesk Plus (SDP) API v3. Мы выясним, почему исходный код автора темы не работал, подробно изучим ограничения HTTP-методов в платформе 1С и реализуем два гарантированно рабочих решения для GET и POST запросов.

Анализ исходной проблемы: почему веб-сервер игнорирует параметры?

Давайте проанализируем исходный код автора и разберем допущенные им ошибки. В своем первом сообщении автор пытается получить данные из ServiceDesk Plus, выполняя GET-запрос с фильтрацией. Для этого он формирует JSON-строку input_data и пытается передать ее двумя способами одновременно:

  1. Через тело запроса с помощью метода УстановитьТелоИзСтроки().
  2. Через HTTP-заголовок: HTTPЗапрос.Заголовки.Вставить("input_data", СтрокаJSN).

Оба этих подхода содержат критические ошибки, из-за которых интеграция дает сбой:

Во-первых, спецификация HTTP-метода GET не предусматривает отправку тела (body). Хотя технически некоторые библиотеки позволяют прикрепить тело к GET-запросу, стандарт RFC и большинство веб-серверов (включая платформу 1С и сам сервер ServiceDesk Plus) либо полностью игнорируют тело в GET-запросах, либо возвращают ошибку. При вызове метода HTTPСоединение.Получить() платформа 1С просто отбрасывает тело запроса, поэтому сервер возвращает данные без учета фильтров.

Во-вторых, параметр input_data не является HTTP-заголовком. Заголовки HTTP используются для служебной информации (например, авторизация, тип контента, кодировка). Попытка передать структуру данных в заголовке бессмысленна — сервер просто проигнорирует неизвестное поле.

В-третьих, при попытке использовать POST-запрос через метод ОтправитьДляОбработки() автор отправляет «чистый» JSON в теле запроса, но оставляет заголовок Content-Type в значении application/x-www-form-urlencoded. В этом формате сервер ожидает данные вида ключ=значение, а не сырой JSON-текст. Это несоответствие и вызывает ошибку на стороне сервера.

Способ №1. Корректная реализация GET-запроса (Передача параметров через Query String)

Давайте разберем, как обойти ограничение GET-запроса на передачу тела. В ServiceDesk Plus API v3 для получения списков (запросы GET) разработчики предусмотрели передачу параметра input_data непосредственно в строке запроса (Query Parameters).

Поскольку JSON содержит спецсимволы (двоеточия, фигурные скобки, кавычки, пробелы), его нельзя передавать в исходном виде в URL-адресе. Строку обязательно нужно закодировать. В 1С для этого используется встроенная функция КодироватьСтроку() со значением кодирования СпособКодированияСтроки.КодировкаURL. Все спецсимволы будут заменены на соответствующие шестнадцатеричные коды (например, пробел превратится в %20).

Рассмотрим по шагам правильную реализацию GET-запроса в 1С:


// Функция выполняет запрос к API и возвращает полученные данные
Функция ПолучитьСписокЗаявокИзServiceDesk() Экспорт
    
    // 1. Формируем структуру параметров
    СтруктураФильтра = Новый Структура;
    СтруктураФильтра.Вставить("name", "8702_MyView");
    
    СтруктураПараметров = Новый Структура;
    СтруктураПараметров.Вставить("row_count", 20);
    СтруктураПараметров.Вставить("start_index", 1);
    СтруктураПараметров.Вставить("filter_by", СтруктураФильтра);
    
    СтруктураList = Новый Структура;
    СтруктураList.Вставить("list_info", СтруктураПараметров);
    
    // 2. Сериализуем структуру в JSON
    СтрокаJSON = СформироватьСтрокуJSON(СтруктураList);
    
    // 3. Кодируем строку JSON для вставки в URL
    ЗакодированныйJSON = КодироватьСтроку(СтрокаJSON, СпособКодированияСтроки.КодировкаURL);
    
    // 4. Формируем адрес ресурса с параметром input_data
    АдресСервиса = "sd-srv-01";
    АдресРесурса = "/api/v3/requests?input_data=" + ЗакодированныйJSON;
    
    // 5. Создаем HTTP-запрос
    HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
    
    // Устанавливаем необходимые заголовки
    HTTPЗапрос.Заголовки.Вставить("Authtoken", "FC645540-6424-4A07-8A05-A865F4B8168A");
    
    // Крайне важный заголовок для API v3, гарантирующий получение ответа в нужном формате
    HTTPЗапрос.Заголовки.Вставить("Accept", "application/vnd.manageengine.sdp.v3+json");
    
    // 6. Выполняем GET-запрос
    HTTPСоединение = Новый HTTPСоединение(АдресСервиса);
    
    Попытка
        Ответ = HTTPСоединение.Получить(HTTPЗапрос);
    Исключение
        ВызватьИсключение "Ошибка при отправке GET-запроса: " + ОписаниеОшибки();
    КонецПопытки;
    
    // 7. Обрабатываем ответ сервера
    Если Ответ.КодСостояния = 200 Тогда
        СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
        Возврат СтрокаОтвета;
    Иначе
        Сообщить("Сервер вернул ошибку с кодом: " + Ответ.КодСостояния);
        Сообщить(Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8));
        Возврат Неопределено;
    КонецЕсли;
    
КонецФункции

Способ №2. Корректная реализация POST-запроса (Передача параметров в теле)

Если ваша задача требует изменения состояния объектов на сервере (например, создание новой заявки или редактирование существующей), то правилами хорошего тона и архитектурой REST предписано использовать метод POST или PUT. В этом случае параметры действительно нужно передавать в теле запроса.

Однако, помня об особенностях работы ServiceDesk Plus с типом контента application/x-www-form-urlencoded, мы должны сформировать тело запроса специальным образом. Оно должно выглядеть как строка вида: input_data=Закодированный_JSON_Текст.

Давайте посмотрим, как реализовать этот алгоритм на практике в 1С:


Процедура СоздатьЗаявкуВServiceDesk(СтруктураДанныхЗаявки)
    
    АдресСервиса = "sd-srv-01";
    АдресРесурса = "/api/v3/requests";
    
    // 1. Сериализуем данные в JSON
    СтрокаJSON = СформироватьСтрокуJSON(СтруктураДанныхЗаявки);
    
    // 2. Создаем HTTP-запрос
    HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
    
    // Настраиваем обязательные заголовки
    HTTPЗапрос.Заголовки.Вставить("Authtoken", "FC645540-6424-4A07-8A05-A865F4B8168A");
    HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
    HTTPЗапрос.Заголовки.Вставить("Accept", "application/vnd.manageengine.sdp.v3+json");
    
    // 3. Формируем тело запроса по стандарту x-www-form-urlencoded
    ЗакодированныйJSON = КодироватьСтроку(СтрокаJSON, СпособКодированияСтроки.КодировкаURL);
    СтрокаТелаЗапроса = "input_data=" + ЗакодированныйJSON;
    
    // Устанавливаем тело запроса
    HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаТелаЗапроса, КодировкаТекста.UTF8);
    
    // 4. Отправляем запрос методом POST
    HTTPСоединение = Новый HTTPСоединение(АдресСервиса);
    
    Попытка
        // Для отправки POST используем ОтправитьДляОбработки
        Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
    Исключение
        ВызватьИсключение "Ошибка при отправке POST-запроса: " + ОписаниеОшибки();
    КонецПопытки;
    
    // 5. Проверяем результат
    Если Ответ.КодСостояния = 200 Или Ответ.КодСостояния = 201 Тогда
        Сообщить("Запрос успешно обработан сервером.");
        Сообщить(Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8));
    Иначе
        Сообщить("Ошибка выполнения POST. Код ответа: " + Ответ.КодСостояния);
        Сообщить(Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8));
    КонецЕсли;
    
КонецПроцедуры

Универсальная сериализация структуры 1С в JSON-строку

Для успешной интеграции критически важно правильно генерировать саму JSON-строку. Платформа 1С:Предприятие предоставляет удобные механизмы потоковой и объектной записи. Давайте напишем вспомогательную функцию, которая быстро преобразует любую переданную структуру 1С в чистую JSON-строку без лишних переносов и служебных символов:


Функция СформироватьСтрокуJSON(ВходнаяСтруктура) Экспорт
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(,,, СпособПредставленияЧиселJSON.Десятичный);
    
    // Настраиваем запись во внутреннюю память
    ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);
    
    // Выполняем сериализацию
    ЗаписатьJSON(ЗаписьJSON, ВходнаяСтруктура, Новый НастройкиСериализацииJSON);
    
    СтрокаJSON = ЗаписьJSON.Закрыть();
    Возврат СтрокаJSON;
    
КонецФункции

Важные технические нюансы интеграции с ServiceDesk Plus API v3

Помимо корректного формирования сетевых запросов, при интеграции с SDP API v3 необходимо помнить о нескольких важных архитектурных особенностях этой системы:

  1. Строгая чувствительность к регистру (Case Sensitivity): В отличие от устаревшего API v1, третья версия API строго проверяет регистр символов ключей в JSON. Все системные поля и параметры (такие как list_info, row_count, filter_by) должны передаваться исключительно в нижнем регистре. Если вы случайно запишете Row_count с большой буквы, сервер вернет ошибку валидации схемы.
  2. Заголовок Accept: Всегда добавляйте заголовок Accept: application/vnd.manageengine.sdp.v3+json. Это сообщает серверу о необходимости использовать именно логику API v3. В противном случае поведение сервера на некоторых версиях ПО может быть непредсказуемым.
  3. Метод авторизации: Обратите внимание, что авторизация по токену через заголовок Authtoken актуальна для On-Premise версий продукта (локальные сервера). Если ваша компания использует облачное решение ServiceDesk Plus Cloud, авторизация строится на базе OAuth 2.0. В этом случае вместо заголовка Authtoken необходимо использовать стандартный заголовок авторизации: Authorization: Zoho-oauthtoken [Ваш_Токен].

Использование предложенных шаблонов кода и понимание специфики работы HTTP-протокола позволит вам быстро и безболезненно настроить интеграцию любой сложности между вашей базой 1С и системой ServiceDesk Plus.

← На главную