GraphQL передает аргументы для субразрешения

У меня есть отношения между пользователем и публикацией. Вот как я запрашиваю сообщения пользователей.

const UserType = new GraphQLObjectType({
  name: 'User'
  fields: () => ({
    name: {
      type: GraphQLString
    },
    posts: {
      type: new GraphQLList(PostType),
      resolve(parent, args , { db }) {
        // I want to get here the args.someBooleanArg
        return someLogicToGetUserPosts();
      }
    }
  })
});

Основной запрос:

const queryType = new GraphQLObjectType({
  name: 'RootQuery',
  fields: {
    users: {
      type: new GraphQLList(UserType),
      args: {
        id: {
          type: GraphQLInt
        },
        someBooleanArg: {
          type: GraphQLInt
        }
      },
      resolve: (root, { id, someBooleanArg }, { db }) => {
        return someLogicToGetUsers();
      }
    }
  }
});

Проблема заключается в том, что аргументы в функции разрешения сообщений UserType являются пустым объектом, как передать аргументы из основного запроса в вспомогательные функции разрешения?


person Community    schedule 27.09.2016    source источник


Ответы (2)


При разрешении корневого запроса вы можете использовать назначение объекта, чтобы присоединить аргумент к возвращаемому объекту пользователя. Затем для типа пользователя разрешите аргумент от корневого значения (первый аргумент функции разрешения).

Пример:

const queryType = new GraphQLObjectType({
  name: 'RootQuery',
  fields: {
    users: {
      type: new GraphQLList(UserType),
      args: {
        id: {
          type: GraphQLInt
        },
        someBooleanArg: {
          type: GraphQLInt
        }
      },
      resolve: (root, { id, someBooleanArg }, { db }) => {
        return Promise.resolve(someLogicToGetUsers()).then(v => {
            return Object.assign({}, v, {
                someBooleanArg
            });
        });
      }
    }
  }
});

const UserType = new GraphQLObjectType({
  name: 'User'
  fields: () => ({
    name: {
      type: GraphQLString
    },
    posts: {
      type: new GraphQLList(PostType),
      resolve(parent, args , { db }) {
        console.log(parent.someBooleanArg);
        return someLogicToGetUserPosts();
      }
    }
  })
});

person HagaiCo    schedule 27.09.2016
comment
Нет ли собственного способа передать его как аргументы в подзапрос вместо изменения объекта ответа? - person carraua; 22.09.2017

Вы можете использовать четвертый аргумент резолвера, info, чтобы получить желаемую переменную - из документации Apollo:

Каждый преобразователь в схеме GraphQL.js принимает четыре позиционных аргумента:

fieldName (объект, аргументы, контекст, информация) {результат}

Эти аргументы имеют следующие значения и условные названия:

obj: объект, который содержит результат, возвращенный преобразователем в родительском поле, или, в случае поля запроса верхнего уровня, rootValue, переданный из конфигурации сервера. Этот аргумент включает вложенный характер запросов GraphQL.

args: объект с аргументами, переданными в поле запроса. Например, если поле было вызвано с именем автора (имя: «Ада»), объект args будет иметь вид: {«имя»: «Ада»}.

контекст: это объект, совместно используемый всеми распознавателями в конкретном запросе, и используется для хранения состояния каждого запроса, включая информацию аутентификации, экземпляры загрузчика данных и все остальное, что следует учитывать при разрешении запрос. Если вы используете Apollo Server, прочтите о том, как установить контекст, в документации по установке.

info: этот аргумент следует использовать только в сложных случаях, но он содержит информацию о состоянии выполнения запроса, включая имя поля, путь к полю из корня и многое другое. Он задокументирован только в исходном коде GraphQL.js.

info кажется очень недокументированной функцией, но я использую ее сейчас без проблем (по крайней мере, пока кто-нибудь не решит ее изменить).

Вот уловка:

const UserType = new GraphQLObjectType({
  name: 'User'
  fields: () => ({
    name: {
      type: GraphQLString
    },
    posts: {
      type: new GraphQLList(PostType),
      resolve(parent, args , { db }, info) {
        // I want to get here the args.someBooleanArg

        console.log("BINGO!");
        console.log(info.variableValues.someBooleanArg);

        return someLogicToGetUserPosts();
      }
    }
  })
});
person Mendes    schedule 14.05.2019
comment
Это неверно, args поля не совпадает с variables вашего запроса. У вас может быть, например, запрос ($ variableId: ID) {user (id: $ variableId) {posts {// здесь вы получите информацию. variableValues.variableId, а не пользовательский args.id}} `` - person Miguel Carvajal; 07.03.2020
comment
это работает только для именованных переменных, если вы используете жестко запрограммированные переменные, они не отображаются - person Dom Barker; 05.03.2021