Как передать корневые параметры в функцию разрешения вложенного запроса?

У меня есть запрос следующего характера

Category1(name: $cat1){
   Category2(secondName: $cat2){
      secondName
    }}

Моя схема такая:

const Query = new GraphQLObjectType({
name: 'Query',
fields: {
    Category1: {
        type: new GraphQLList(Category1Type),
        args: { name },
        resolve: resolveCategory1
    }}
})

И тогда Category1Type определяется как:

const Category1Type = new GraphQLObjectType({
    name: 'Category1',
    description: '<>',
    fields: () => ({
        name: { type: GraphQLString },
        category2: {
            type: new GraphQLList(CategoryType2),
            args: { secondName },
            resolve: resolveCategory2
        }
    })
});

Для простоты предположим, что категория 2 выглядит так:

const Category2Type = new GraphQLObjectType({
    name: 'Category2',
    description: '<>',
    fields: () => ({
        name: { type: GraphQLString },
    })
});

Теперь я хочу получить все элементы категории 2 в категории 1 с возможностью фильтрации, например:

Category1(name: $name){
   name
   category2(name: $name){
      name 
}}

Мои преобразователи определены так:

    # Category1 resolver
    function cat1resolve (root, args) {
return SELECT * from data WHERE category1_name = args.name
}

    # Category2 resolver
    function cat2Resolve (root, args) {
return SELECT * from data WHERE category1_name = rootargs.name and categort2_name = args.secondName }

Теперь проблема в том, что «преобразователь» для cat2Resolve не может видеть или получать rootargs.name, чтобы я мог выполнять такую ​​​​фильтрацию.


person CoderBC    schedule 04.01.2018    source источник
comment
Похоже проблема в вашей схеме. Пожалуйста, обновите свой вопрос, включив в него схему или, по крайней мере, части, относящиеся к этим трем типам.   -  person Daniel Rearden    schedule 04.01.2018
comment
Спасибо за обновление вопроса :) Итак, чтобы уточнить, проблема, с которой вы столкнулись, связана не с ошибкой, о которой вы упоминали ранее, а с тем, что преобразователь для категории 2 не работает должным образом? Было бы полезно включить фактический код распознавателя и неожиданное поведение, которое вы видите при выполнении запроса.   -  person Daniel Rearden    schedule 04.01.2018
comment
@DanielRearden Я попытался объяснить точную операцию дальше   -  person CoderBC    schedule 04.01.2018


Ответы (1)


Сигнатура функции разрешения включает 4 параметра. Из документов компании Apollo:

  1. obj: объект, который содержит результат, возвращенный преобразователем для родительского поля, или, в случае поля запроса верхнего уровня, значение rootValue, переданное из конфигурации сервера. Этот аргумент включает вложенный характер запросов GraphQL.
  2. args: объект с аргументами, переданными в поле запроса. Например, если поле было вызвано с автором (имя: «Ада»), объект args будет: { «имя»: «Ада» }.
  3. контекст: это объект, совместно используемый всеми преобразователями в конкретном запросе, который используется для хранения состояния каждого запроса, включая информацию об аутентификации, экземпляры загрузчика данных и все остальное, что следует учитывать при разрешении запроса. Если вы используете сервер Apollo, прочитайте о том, как установить контекст в документации по установке.
  4. информация: этот аргумент следует использовать только в сложных случаях, но он содержит информацию о состоянии выполнения запроса, включая имя поля, путь к полю от корня и многое другое. Это задокументировано только в исходном коде GraphQL.js.

Примечание. Эти документы предназначены для графических инструментов makeExecutableSchema (которые я настоятельно рекомендую), но то же самое относится и к простому старому GraphQL.JS.

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

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

Используя что-то вроде get из lodash, мы можем сделать:

const category1id = get(info, 'operation.selectionSet.selections[0].arguments[0].value.value')

и используйте это значение внутри вашего запроса. Вышеупомянутое довольно хрупкое, так как предполагается, что ваш запрос содержит только один запрос, и у вас есть только один аргумент в поле Category1. На практике вы, вероятно, захотите использовать Array.find и искать поля/аргументы по имени, но это должно дать вам отправную точку.

person Daniel Rearden    schedule 04.01.2018