Разбиение на страницы GraphQL: курсор против смещения

нам нужно перестроить серверное приложение на основе служб REST, и, поскольку у нас много вложенных уровней в службах, мы решили внедрить инновации и попробовать GraphQL.

Мы начали делать простые вещи, и проект выглядел очень многообещающе, однако мы столкнулись с реальными проблемами, такими как нумерация страниц. В REST подход к разбиению на страницы был простым, мы используем метод GET с некоторыми параметрами, такими как pageSize и pageNumber (или offset), и создаем SQL-запросы для выполнения этого разбиения на страницы.

В GraphQL мы решали проблему, используя тот же подход, например, имея такой запрос:

users(size:5 offset:2) {
  id
  name
}

Этот подход выглядел простым в реализации, однако, копнув глубже, мы обнаружили, что «лучшим» шаблоном для его реализации является Connection, для которого запрос будет выглядеть следующим образом:

users(first:2) {
  totalCount
  edges {
    node {
      name
    }
    cursor
  }
  pageInfo {
    endCursor
    hasNextPage
  }
}

Наши данные сохраняются в реляционной базе данных, поэтому я не вижу, как курсоры могут помочь (разве что, если я использую идентификатор автоинкремента?).

Почему этот сложный подход предпочтительнее простого? А также какой курсор и endCursor будут хранить? Я что-то неправильно понимаю в своем пути обучения?


person Federico Piazza    schedule 11.08.2018    source источник


Ответы (1)


Спецификация Connection изначально была создана для Relay (клиент Facebook GraphQL). Позже он зажил своей собственной жизнью и теперь считается лучшей практикой, независимо от клиента. Но (и это огромное но), это определенно не подходит для каждого варианта использования.

Если вы видите ценность в реализации стиля нумерации страниц Connection, у вас есть 2 варианта:

1) Рассматривайте after как смещение (что означает, что число будет передано), а first как ограничение:

SELECT * FROM ORDER BY timestamp OFFSET $after LIMIT $first

То же самое для before и last, только в другом направлении.

2) Другой способ - рассматривать after/before как последнее увиденное значение столбца сортировки (чтобы было передано фактическое (запутанное) значение):

SELECT * FROM ORDER BY timestamp WHERE timestamp > $after LIMIT $first

Тем не менее, если вам не подходит подход Connection, смело игнорируйте его. Особенно, если вы даже не используете Relay в качестве клиента. Это совершенно необязательная вещь, и ее не следует впихивать туда, где она неуместна.

person kaqqao    schedule 23.08.2018