Есть ли хороший способ объединить преобразователи для нескольких объектов GraphQL, предпочтительно с использованием graphql-js?

Предположим, у вас есть уровень GraphQL, написанный на node.js с использованием graphql-js, который взаимодействует с базой данных SQL. Предположим, у вас есть следующие простые типы и поля:

  • Магазин
    Единая физическая локация для сети продуктовых магазинов.
    Поля:

    • id: GraphQLID
    • регион: StoreRegion
    • сотрудники: GraphQLList (Сотрудник)
  • МагазинRegion
    GraphQLEnumType, содержащий список регионов, на которые сеть делит свои магазины. Значения:

    • К СЕВЕРО-ВОСТОКУ
    • МИДАТЛАНТИЧЕСКИЙ
    • ЮГО-ВОСТОК
    • ...
  • Сотрудник Представляет одного сотрудника, работающего в магазине. Поля:

    • id: GraphQLID
    • имя: GraphQLString
    • зарплата: GraphQLFloat

Предположим, что API предоставляет запрос store, который принимает регион и возвращает список объектов Store. Теперь предположим, что клиент отправляет этот запрос:

{
    store(region: NORTHEAST) {
        employees {
            name
            salary
        }
    }
}

Надеюсь, пока все довольно просто.

Итак, вот мой вопрос, и я надеюсь (действительно ожидаю), что это что-то, что имеет общее решение, и у меня просто возникают проблемы с его поиском, потому что мой Google-Fu сегодня слаб: есть ли хороший способ, чтобы я мог написать резолверы для этих типов, так что я могу заключить все запрошенные поля для всех сотрудников из всех возвращенных хранилищ в один запрос SQL, что приведет к одному обращению к базе данных формы:

SELECT name,salary FROM employees WHERE id IN (1111, 1133, 2177, ...)

вместо того, чтобы делать один запрос на сотрудника или даже один запрос на магазин?

Это действительно конкретный пример более общего вопроса: есть ли хороший способ объединить преобразователи, чтобы избежать выполнения нескольких запросов в тех случаях, когда их можно легко объединить?

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

Хотя это определенно возможно, это по сути оптимизирует один конкретный запрос к вашему API. Если вы еще не знаете наверняка, что вы столкнетесь с проблемами производительности как только вы развернете, вероятно, наиболее прагматично использовать простые решатели и оптимизировать проблемные запросы, как только они станут проблемой :-) В противном случае вы, вероятно, получите много одноразовых оптимизаций, которые делают меняется намного сложнее.

Mike Marcacci 28.03.2018 02:33
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
4
1
909
1

Ответы 1

Итак, в основном вам интересно, как можно объединить несколько преобразователей в меньшее количество запросов к базе данных. Это пытается решить то, что они называют Проблема с запросом N + 1. Вот как минимум два способа решить эту проблему.

  1. DataLoader: Это более общее решение, созданное Facebook. Вы можете использовать это для пакетирования нескольких запросов, которые запрашивают один элемент одного типа, в один запрос, который запрашивает несколько элементов одного типа. В вашем примере вы объедините всех сотрудников в один запрос к БД, и у вас все равно будет отдельный запрос для получения магазина. Вот такой видео Бена Авада, объясняющее DataLoader

  2. JoinMonster: Специально для SQL. Будет выполнять JOINs, чтобы сделать один SQL-запрос на каждый запрос graphql. Вот такой видео Бена Авада, объясняющее JoinMonster

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