Введение

Relay Спецификация соединения курсора GraphQL иллюстрирует, как реализовать разбиение на страницы на основе курсора в GraphQL. Однако многие разработчики хотят упорядочивать получаемые данные. В этой статье мы рассмотрим, как включить упорядочение в ваши соединения курсора.

Исходная схема

Чтобы предоставить примеры в этой статье, мы расширим следующую схему, в которой уже реализованы соединения курсора.

# Example Original Schema

type Query {
  users(
    first: Int,
    after: String
  ): UserConnection
  products(
    first: Int,
    after: String
  ): ProductConnection
  reviews(
    first: Int,
    after: String
  ): ReviewConnection
}

type User {
  id: ID!
  name: String!
}

type UserEdge {
  node: User
  cursor: String
}

type UserConnection {
  edges: [UserEdge]
  pageInfo: PageInfo
}

type Product {
  id: ID!
  upc: String!
  price: Float!
  inStock: Boolean!
}

type ProductEdge {
  node: Product
  cursor: String
}

type ProductConnection {
  edges: [ProductEdge]
  pageInfo: PageInfo
}

type Review {
  id: ID!
  body: String!
}

type ReviewEdge {
  node: Review
  cursor: String
}

type ReviewConnection {
  edges: [ReveiwEdge]
  pageInfo: PageInfo
}

type PageInfo {
  endCursor: String
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
}

Зарезервированные типы

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

  • Любой ввод, имя которого заканчивается на «OrderByInput».
  • Перечисление с именем «SortOrder».

Упорядочить по входам

Любой ввод, имя которого оканчивается на «OrderBy», рассматривается этой спецификацией как Order By Input. Заказ по входам должен иметь одно или несколько полей, связанных с заказом.

  • «Где ввод» должен иметь одно или несколько полей, связанных с заказом. Эти поля входят в перечисление «SortOrder».
# Example Order By Inputs

input UserOrderByInput {
  name: SortOrder
}

input ProductOrderByInput {
  upc: SortOrder
  price: SortOrder
  inStock: SortOrder
}

input ReviewOrderByInput {
  body: SortOrder
}

Порядок сортировки

Перечисление с именем «SortOrder» рассматривается этой спецификацией как Порядок сортировки. Перечисление Sort Order должно иметь две константы: по возрастанию и по убыванию.

  • «Порядок сортировки» должен иметь константу «ПО ВОЗРАСТУ», указывающую, что поле должно быть упорядочено в порядке возрастания.
  • «Порядок сортировки» должен иметь константу «ПО УБЫВАНИЮ», указывающую, что поле должно быть упорядочено в порядке убывания.
# Example Sort Order

enum SortOrder {
  ASCENDING
  DESCENDING
}

Аргументы

Для включения упорядочения требуется один аргумент. Сервер должен использовать этот аргумент для упорядочения ребер, возвращаемых соединением, возвращая ребра, порядок которых соответствует применяемому порядку.

  • Запрос «Соединение» должен содержать аргумент с именем «orderBy». Этот аргумент принимает тип списка, который является оболочкой «Упорядочить по входу».
# Example Queries w/ Arguments

type Query {
  users(
    first: Int,
    after: String,
    orderBy: [UserOrderByInput!]
  ): UserConnection
  products(
    first: Int,
    after: String,
    orderBy: [ProductOrderByInput!]
  ): ProductConnection
  reviews(
    first: Int,
    after: String,
    orderBy: [ReviewOrderByInput!]
  ): ReviewConnection
}

Пример запроса

Упорядочивая соединения курсора, вы можете делать такие запросы, как:

query GetProductConnection(
  $first: Int,
  $after: String,
  $orderBy: [ProductOrderByInput!]
) {
  products(
    first: $first,
    after: $after,
    orderBy: $orderBy
  ) {
    edges {
      node {
        id
        upc
        price
      }
    }
  }
}
{
  "first": 1000,
  "after": "7b20226976223a2022363936653639373436393631366336393761363137343639366636653230373636353633373436663732222c202264617461223a2022363536653633366636343635363432303633373537323733366637323230363436313734363122207d",
  "orderBy": [
    {
      "inStock": "ASCENDING"
    },
    {
      "price": "DESCENDING"
    }
  ]
}

Заключение

Расширяя спецификацию соединения курсора GraphQL с возможностями упорядочивания, наши графики могут сначала предоставлять клиентам приоритетные данные. Включение упорядочения в разбиение на страницы на основе курсора требует определения пользовательских входных данных, обновления аргументов соединения, изменения преобразователей и обработки генерации курсора.