Разметка 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 будут хранить? Я неправильно понимаю что-то на своем пути обучения?

1 ответ

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

Если вы видите ценность в реализации Connection стиль нумерации страниц, вы всегда можете решить рассматривать курсор как смещение. Например, спецификация определяет 2 аргумента before а также after это курсоры. Вы можете просто решить поместить смещение внутрь. 2 других аргумента, first а также last, не нужно никакого специального лечения. Логика остается точно такой, как задумано.

Например, вместо

users(size:5 offset:2) { ... } //Get 5 after the first 2

ты получаешь

users(first:5 after:2) { ... } //Get first 5 after the 2nd - exactly the same

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

Другие вопросы по тегам