Как реализовать бэкэнд для подключений GraphQL? - PullRequest
0 голосов
/ 02 октября 2018

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

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

Проблема в том, что SQL не знает ничего, как курсоры GraphQL, - мы не можем сказать,это выбрать все строки после определенной строки.Есть только ГДЕ, СМЕЩЕНИЕ и ОГРАНИЧЕНИЕ.С моей точки зрения кажется, что мне нужно сначала выбрать одну строку на основе курсора, а затем построить второй запрос SQL, используя значения столбцов сортировки в этой строке, чтобы указать сложное предложение WHERE - не уверен, что база данных будет использоватьindex в этом случае.

Меня беспокоит то, что я не смог найти ни одной статьи на эту тему.Означает ли это, что база данных SQL обычно не используется при реализации сервера GraphQL?Какую базу данных следует использовать тогда?Как запросы GraphQL к полям подключения обычно преобразуются в запросы для базовой базы данных?

РЕДАКТИРОВАТЬ: Это более или менее то, что я придумал сам.Проблема заключается в том, как расширить его для поддержки сортировки и как эффективно реализовать его с использованием индексов базы данных.

1 Ответ

0 голосов
/ 03 октября 2018

Хитрость здесь в том, что, как разработчик сервера, курсор может быть буквально любым значением, которое вы хотите закодировать как строку.Большинство примеров, которые я видел, были закодированы в base64 для немного непрозрачности, но это не обязательно.(Попробуйте, например, base64-декодирование курсоров из примеров Star Wars в вашей ссылке.)

Допустим, ваша схема GraphQL выглядит как

enum ThingColumn { FOO BAR }
input ThingFilter {
  foo: Int
  bar: Int
}
type Query {
  things(
    filter: ThingFilter,
    sort: ThingColumn,
    first: Int,
    after: String
  ): ThingConnection
}

Ваш первый запрос может быть

query {
  things(filter: { foo: 1 }, sort: BAR, first: 2) {
    edges {
      node { bar }
    }
    pageInfo {
      endCursor
      hasNextPage
    }
  }
}

Само по себе это может довольно прямо переводиться в SQL-запрос, например

SELECT bar FROM things WHERE foo=1 ORDER BY bar ASC LIMIT 2;

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

{
  "data": {
    "things": {
      "edges": [
        { "node": { "bar": 17 } },
        { "node": { "bar": 42 } }
      ],
      "pageInfo": {
        "endCursor": "2",
        "hasNextPage": true
      }
    }
  }
}

Затем, когда следующий запрос скажет after: "2", вы можете превратить его обратно в SQL OFFSET и повторить запрос.

Если выПытаясь создать общий интерфейс GraphQL, который переводится на достаточно общие запросы SQL, невозможно создать индексы, которые бы выполняли каждый запрос «быстро».Как и в других случаях, вам нужно выяснить, каковы ваши общие и / или медленные запросы и CREATE INDEX при необходимости.Возможно, вы сможете ограничить параметры в своей схеме теми вещами, которые, как вы знаете, можете индексировать:

type Other {
  things(first: Int, after: String): ThingConnection
}
query OtherThings($id: ID!, $cursor: String) {
  node(id: $id) {
    ... on Other {
      things(first: 100, after: $cursor) { ... FromAbove }
    }
  }
}
SELECT * FROM things WHERE other_id=? ORDER BY id LIMIT ?;
CREATE INDEX things_other ON things(other_id);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...