При интеграции 1С с внешними сайтами и сервисами через HTTP-запросы часто возникает задача получения не всех данных подряд, а только определенной выборки, например, за определенный период или по дате создания записи. Разберем по шагам, как устроен механизм передачи параметров в GET-запросах, как правильно сформировать адрес ресурса в 1С и как обработать полученный ответ.
Протокол HTTP в методе GET не предусматривает отправку тела сообщения (payload). Все параметры фильтрации, пагинации (постраничной навигации) и сортировки передаются непосредственно в строке адреса ресурса (Query String). Проанализируем базовые правила формирования такой строки:
?.ключ=значение.&.Важно понимать, что обработка параметров происходит исключительно на стороне веб-сервера. Если в API сайта разработчик не заложил поддержку конкретного фильтра, сервер проигнорирует переданный параметр и вернет стандартный список. Поэтому первоочередная задача — свериться с документацией API или уточнить у разработчиков сервиса точные имена параметров.
Если документация отсутствует или ограничена, на практике чаще всего встречаются следующие варианты именования параметров отбора по дате:
created_at=2017-04-13, date=2017-04-13.created_at_from=2017-04-01&created_at_to=2017-04-30, from=...&to=..., date_from=...&date_to=..., since=...&until=....filter[created_at]=... или filter[created_at][gte]=...&filter[created_at][lte]=....$filter=created_at ge datetime'2017-04-13T00:00:00'.Проанализируем исходный код формирования запроса и устраним распространенные технические неточности:
Content-Type не имеет смысла, данный заголовок является избыточным.<item>), заголовок Accept: application/json может приводить к ошибкам либо к попытке сервера преобразовать ответ. Если нам нужен XML, следует указывать application/xml или text/xml.UTF-8. Чтение тела ответа также следует выполнять в кодировке UTF-8 или без параметров (по умолчанию платформа использует UTF-8).HTTPСоединение необходимо передать объект ЗащищенноеСоединениеOpenSSL.Посмотрим на пример кода 1С, в котором формируются параметры фильтрации, выполняется URL-кодирование и отправляется GET-запрос:
Сервер = "мойсайт.рф";
БазовыйАдрес = "/api/items";
// Подготовим значения параметров
НомерСтраницы = 1;
ДатаНачала = '20170413000000';
СтрокаДаты = Формат(ДатаНачала, "ДФ=yyyy-MM-dd");
// Выполняем экранирование параметров для URL
ЗакодированнаяДата = КодироватьСтроку(СтрокаДаты, СпособКодированияСтроки.КодировкаURL);
// Собираем строку запроса с отбором и пагинацией
ПараметрыЗапроса = "page=" + НомерСтраницы + "&created_at_from=" + ЗакодированнаяДата;
АдресРесурса = БазовыйАдрес + "?" + ПараметрыЗапроса;
// Инициализируем защищенное соединение (при необходимости)
Защита = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение(Сервер, 443, , , , 30, Защита);
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
HTTPЗапрос.Заголовки.Вставить("Accept", "application/xml, text/xml");
ОтветСервера = HTTPСоединение.Получить(HTTPЗапрос);
Если ОтветСервера.КодСостояния = 200 Тогда
ТелоОтвета = ОтветСервера.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
// Переходим к парсингу полученных данных
Иначе
ВызватьИсключение "Ошибка HTTP-запроса: " + ОтветСервера.КодСостояния;
КонецЕсли;
После успешного получения ответа данные необходимо разобрать. Для эффективной работы с XML-документами в платформе 1С предусмотрен объект ЧтениеXML, который позволяет последовательно прочитать все узлы без избыточной нагрузки на оперативную память:
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(ТелоОтвета);
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента И Чтение.Имя = "item" Тогда
// Считываем данные одного элемента
ТекущийID = "";
ТекущееИмя = "";
ТекущаяДатаСоздания = "";
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяУзла = Чтение.Имя;
Чтение.Прочитать(); // Переход к текстовому значению
Если ИмяУзла = "id" Тогда
ТекущийID = Чтение.Значение;
ИначеЕсли ИмяУзла = "first_name" Тогда
ТекущееИмя = Чтение.Значение;
ИначеЕсли ИмяУзла = "created_at" Тогда
ТекущаяДатаСоздания = Чтение.Значение;
КонецЕсли;
ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента И Чтение.Имя = "item" Тогда
Прервать; // Завершили чтение элемента
КонецЕсли;
КонецЦикла;
// Обработка полученных значений (запись в справочник, ТЗ и т.д.)
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
В ситуации, когда разработчик сайта не реализовал серверную фильтрацию и связаться с ним невозможно, единственным выходом остается постраничный обход всех данных через цикл по параметру page и наложение отбора внутри 1С:
page=1, page=2 и т.д.).<item>.Дата значение поля <created_at> с требуемым периодом.