Как реализовать постраничную загрузку (пагинацию) данных из JSON в 1С?

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

При интеграции 1С с внешними информационными системами через HTTP-сервисы разработчики часто сталкиваются с ситуацией, когда сервер возвращает данные не целиком, а частями. Это называется пагинацией (или постраничным выводом). В данной статье мы подробно разберем, как правильно обрабатывать такие ответы, какие методы «листания» страниц существуют и как обеспечить целостность полученных данных.

Анализ исходной ситуации

Рассмотрим типичный пример ответа от сервера. При использовании функции ПрочитатьJSON() разработчик получает структуру, содержащую массив элементов и метаданные о количестве страниц:


// Пример структуры ответа
// Items: Массив (данные текущей страницы)
// NextPage: 2 (номер следующей страницы)
// TotalItems: 98695 (общее количество записей)
// TotalPages: 10 (всего страниц)

Проанализируем ситуацию: объект Items содержит только часть данных. Чтобы получить все 98 695 записей, нам необходимо выполнить дополнительные запросы к API, сообщая серверу, какую именно «порцию» данных мы хотим получить в данный момент.

Метод 1: Пагинация на основе смещения (Offset-based)

Это самый распространенный метод. Мы сообщаем серверу номер страницы (page) или количество записей, которые нужно пропустить (offset), и лимит записей на одну страницу (limit).

Разберем по шагам, как реализовать цикл загрузки всех страниц в 1С:

  1. Выполняем первый запрос для получения общего количества страниц (TotalPages).
  2. Организуем цикл от 1 до TotalPages.
  3. Внутри цикла формируем HTTP-запрос с параметром страницы.
  4. Декодируем JSON и добавляем полученные элементы в общую таблицу значений или массив.

Пример кода для обхода всех страниц:


ВсегоСтраниц = ДанныеПервогоОтвета.TotalPages;
ОбщиеДанные = Новый Массив;

Для НомерСтраницы = 1 По ВсегоСтраниц Цикл
    // Формируем URL с параметром страницы, например: /api/items?page=2
    ПараметрыЗапроса = "?page=" + Формат(НомерСтраницы, "ЧГ=0");
    Ответ = ВыполнитьЗапросКСерверу(ПараметрыЗапроса); 
    
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(Ответ);
    СтруктураСтраницы = ПрочитатьJSON(ЧтениеJSON);
    
    Для Каждого Элемент Из СтруктураСтраницы.Items Цикл
        ОбщиеДанные.Добавить(Элемент);
    КонецЦикла;
    
    ЧтениеJSON.Закрыть();
КонецЦикла;

Важное замечание: Метод со смещением имеет существенный недостаток. Если во время загрузки (например, между запросом 2-й и 3-й страницы) в базе данных сервера появится новая запись, данные могут «сдвинуться». В результате вы можете получить дубль записи, которая уже была на предыдущей странице, или пропустить одну из записей.

Метод 2: Пагинация через указатели или курсоры (Keyset Pagination)

Более продвинутые API (например, Ozon или крупные ERP-системы) используют параметр last_id или cursor. Вместо номера страницы вы передаете идентификатор последнего объекта, который получили в предыдущем запросе.

Выясним причину популярности этого метода: он гораздо быстрее работает на стороне сервера базы данных, так как поиск по индексу WHERE id > last_id эффективнее, чем пропуск тысяч строк через OFFSET. Кроме того, этот метод устойчив к вставке новых записей в начало списка.

Проанализируем алгоритм работы с курсором:

  1. Первый запрос отправляется без идентификатора.
  2. Из ответа извлекается last_id (самый последний элемент в массиве).
  3. Следующий запрос отправляется с параметром after_id = last_id.
  4. Цикл продолжается до тех пор, пока сервер возвращает непустой массив данных.

Оптимизация и проверка целостности

При работе с большими объемами данных (как в примере автора — почти 100 000 записей) важно соблюдать правила безопасности и производительности:

1. Использование потокового чтения JSON. Если попытаться прочитать JSON объемом в несколько сотен мегабайт в одну Структура, 1С может аварийно завершиться из-за нехватки памяти. В таких случаях используйте объект ЧтениеJSON в режиме последовательного чтения:


ЧтениеJSON.Прочитать(); // Начинаем чтение
Пока ЧтениеJSON.Прочитать() Цикл
    Если ЧтениеJSON.ТипУзла = ТипУзлаJSON.ИмяСвойства И ЧтениеJSON.Значение = "Items" Тогда
        // Начинаем читать массив элементов по одному
        ЧтениеJSON.Прочитать(); // Переход к началу массива
        Пока ЧтениеJSON.Прочитать() Цикл
            Если ЧтениеJSON.ТипУзла = ТипУзлаJSON.КонецМассива Тогда Прервать; КонецЕсли;
            ОбъектЭлемент = ПрочитатьJSON(ЧтениеJSON); // Читаем один объект
            ЗаписатьДанныеВБД(ОбъектЭлемент); // Сразу сохраняем, не копим в памяти
        КонецЦикла;
    КонецЕсли;
КонецЦикла;

2. Контроль дублей. Как справедливо отмечено в обсуждении, при постраничной загрузке всегда есть риск получить одни и те же данные дважды. Рекомендуется сначала загружать данные во временную ТаблицаЗначений, а затем выполнять метод Свернуть() по уникальному идентификатору или проверять наличие записи в базе данных перед записью.

3. Обработка ошибок сети. При загрузке 10 или 100 страниц вероятность сетевого сбоя крайне высока. Обязательно используйте конструкцию Попытка...Исключение и реализуйте механизм повторных попыток (например, 3 попытки с паузой в 2 секунды) для каждой страницы.

4. Параллельная загрузка. Если сервер позволяет делать несколько запросов одновременно, для ускорения процесса можно использовать ФоновыеЗадания. Каждое задание может отвечать за свой диапазон страниц, после чего результаты объединяются в основной сессии.

Заключение

Реализация «листания» страниц в 1С требует не только умения работать с HTTPЗапрос и ЧтениеJSON (для этого отлично подойдет обучающий курс по HTTP-запросам), но и понимания логики работы конкретного API. Всегда уточняйте в документации к сервису, какой метод пагинации используется (Offset или Cursor), и закладывайте механизмы проверки целостности данных, чтобы избежать появления дублей в вашей информационной базе.

← На главную