awesome-everything EN
↑ Обратно к восхождению

API

Pagination: миграция offset-ленты на keyset

Суть Практический проект — соберите offset list-эндпоинт, воспроизведите его медленность на глубине и дрейф при записи, затем мигрируйте на keyset cursor API и докажите исправление числами до/после.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 220 min

Прочитать, что offset умирает на глубине, не то же самое, что увидеть, как страница 10000 уходит в таймаут и как пользователь получает один и тот же пост дважды. Соберите сломанную версию, воспроизведите оба отказа с доказательствами, затем мигрируйте на keyset cursor API и докажите каждое исправление измерениями.

Цель

Превратите ментальную модель юнита в воспроизводимый инженерный цикл: засейте большую таблицу, продемонстрируйте стоимость offset на глубине и дрейф при записи, спроектируйте корректный keyset cursor (уникальный ключ, совпадающий индекс, opaque-кодирование, n+1 hasNextPage) и проверьте плоскую задержку и нулевой дрейф при конкурентных записях.

Проект
0 из 7
Цель

Возьмите list-эндпоинт на большой таблице, продемонстрируйте, что offset pagination и медленна на глубине, и некорректна при конкурентных записях, затем мигрируйте на keyset cursor API, остающийся плоским и стабильным — доказывая каждое утверждение измерениями до/после, а не словами.

Требования
Критерии приёмки
  • Таблица до/после: задержка страниц 1, 1k, 10k для offset против keyset плюс 'actual rows', прочитанные на каждой глубине — измеренные под EXPLAIN ANALYZE, а не оценённые.
  • Задержка keyset плоская на всех глубинах (в пределах нормального разброса), а использование составного индекса подтверждено (Index Scan, без лишней сортировки) в плане.
  • Тест конкурентности показывает задокументированный дубликат/пропуск под offset и ноль дубликатов или пропусков под keyset при той же нагрузке вставок/удалений.
  • Короткое описание: какой уникальный ключ сортировки выбран и почему, как кодируется/декодируется opaque cursor, как выводится hasNextPage и что заменило точный подсчёт и почему.
Senior-стретч
  • Добавьте двунаправленную пагинацию (before/after, first/last) по-Relay: переверните оператор сравнения и направление ORDER BY, затем разверните возвращаемый срез, чтобы клиент видел стабильный порядок. Проверьте, что движение назад возвращает ровно страницы вперёд в обратном порядке.
  • Добавьте offset-поверхность рядом с keyset для ограниченной админской таблицы, которой действительно нужен 'переход на страницу N', и задокументируйте, почему две стратегии сосуществуют для тех же данных.
  • Добавьте защиту от подмены cursor: подписывайте или валидируйте opaque cursor, чтобы рукотворный cursor не уходил в дорогие диапазоны seek, и покажите, что некорректный cursor отвергается чисто, а не сканирует.
  • Повторите эксперимент на не-временной сортировке (например, ORDER BY score DESC, id DESC, где score сильно совпадают) и покажите, что tiebreaker предотвращает дубликаты на стыке, которые дал бы только score.
Итог

Это миграция, которую вы будете выполнять на реальных list-эндпоинтах: сначала докажите отказы offset — стоимость скана глубокой страницы из плана и дрейф дубликат/пропуск при конкурентных записях — затем замените позицию на значение. Уникальный индексированный кортеж (created_at, id), opaque cursor, n+1 зонд hasNextPage и убранный или оценённый подсчёт превращают ленту, умирающую на глубине, в ленту, остающуюся плоской и корректной. Сделав это раз на засеянной таблице, вы переводите продакшен-версию в мышечную память — и понимаете, когда offset всё ещё верный инструмент.

Продолжить восхождение ↑OpenAPI: сделать контракт источником истины, а не доками
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.