Аргументы резольвера express-graphql пусты в резолвере, но информация variableValues ​​заполнена именем и значением - PullRequest
0 голосов
/ 16 апреля 2019

Используя 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 первый параметр execute argsOrSchema.variableValues содержит ключ и значение аргумента запроса, однако 5-й аргумент variableValues не определен.

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

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

1 Ответ

1 голос
/ 17 апреля 2019

Параметр 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, чтобы получить больше примеров и полное объяснение работы распознавателей.

...