Аргументы распознавателя express-graphql пусты в распознавателе, но информация о переменных значениях заполнена именем и значением

Используя apollo-server-express и graphql-tools, я пытаюсь создать минимально жизнеспособную схему из объекта JSON:

const books = [
  {
    "title": "Harry Potter",
    "author": 'J.K. Rowling',
    "slug": "harry_potter",
  },
  {
    "title": 'Jurassic Park',
    "author": 'Michael Crichton',
    "slug": "jurassic_park",
  },
];

// The GraphQL schema in string form
const typeDefs = `
  type Query {
    books: [Book]
    book(title: String!): Book
  }
  type Book { title: String!, author: String!, slug: String! }
`;

// The resolvers
const resolvers = {
  Query: {
    books: () => books,
    book: (_, { title }) => books.filter(book => {
      return new Promise((resolve, reject) => {
        if(book.title == title) {
          console.log('hack log resolve book _: ', JSON.stringify(book))
          resolve(JSON.stringify(book));
        }
      })
    }),
   },
   Book: {
     title: (root, args, context, info) => {
       //args is empty, need to match arg w book.title
       /*
       context:  {
        _extensionStack:
         GraphQLExtensionStack {
           extensions: [ [FormatErrorExtension], [CacheControlExtension] ]
         }
       }
       , root,
       */
       console.log('resolve Book args: ', args, 'info', info);//JSON.stringify(root.book))
       return books.filter(book => {
         if(book.title == root.title) {
           return book;
         }
       });//JSON.stringify({"title": root.title});
     }
   }
};
//    book: (_, { title }) => books.filter(book => book.title == title),


// Put together a schema
const schema = makeExecutableSchema({
  typeDefs,
  resolvers,
});

Это мой репозиторий.

При регистрации и пошаговом выполнении node_modules/graphql/execution/execute.js первый параметр выполнения argsOrSchema.variableValues содержит ключ и значение аргумента запроса, однако 5-й аргумент variableValues не определен.

Согласно некоторым темам, таким как эта проблема GitHub, я могу вытащить variableValues из info моего распознавателя, однако мне все же хотелось бы знать, почему объект args пуст?

Вот суть информационного журнала, предоставленного GraphQL в функции распознавания


person mibbit    schedule 16.04.2019    source источник


Ответы (1)


Параметр args заполняется аргументами, переданными в разрешаемое поле. Любые аргументы, переданные в другие поля, не будут включены в параметр args.

Ваша схема включает один аргумент (title) в поле book вашего типа Query. Это означает, что преобразователь для этого поля получит аргумент title как часть своего параметра args, но только если этот аргумент действительно включен в ваш запрос:

// Request
query {
  book(title: "Something") {
    title
  }
}

// Resolvers
const resolvers = {
  Query: {
    book: (root, args) => {
      console.log(args) // {title: 'Something'}
    }
  },
}

В отличие от:

// Request
query {
  book {
    title
  }
}

// Resolvers
const resolvers = {
  Query: {
    book: (root, args) => {
      console.log(args) // {}
    }
  },
}

Если вы передаете значение для аргумента title, единственный способ получить это значение в преобразователях для других полей — проанализировать параметр info. Вы бы не смотрели на свойство variableValues, потому что значение, переданное аргументу, могло быть буквальным значением или переменной. Вам нужно будет пройтись по массиву fieldNodes и вместо этого найти соответствующее значение аргумента.

Однако, как правило, нет необходимости проходить через все это.

Если предполагается, что поле book просто возвращает объект книги, ваша логика для выбора правильной книги из массива books должна быть включена в преобразователь этого поля:

const resolvers = {
  Query: {
    book: (root, args) => {
      return books.find(book => book.title === args.title)
    }
  },
}

Нет причин включать преобразователь для поля title в тип Book, если только вам не нужно, чтобы это поле разрешалось во что-то отличное от того, во что оно разрешается по умолчанию (свойство title в объекте, возвращаемом преобразователем родительского поля). Этого будет достаточно, чтобы запросить все книги и отдельную книгу по названию:

const resolvers = {
  Query: {
    book: (root, args) => {
      return books.find(book => book.title === args.title)
    },
    books: () => books,
  },
}

Ознакомьтесь с официальным руководством от Apollo, где вы найдете дополнительные примеры и полное объяснение того, как работают преобразователи. .

person Daniel Rearden    schedule 16.04.2019