GraphQL: ошибка при определении GraphQLList с настраиваемым типом в GraphQLObjectType

Я хочу изучить GraphQL и пишу пример, представляющий книжный магазин, где пользователи могут быть авторами нескольких книг.

Моя проблема в том, что я не могу определить список типа "BookType" в UserType (GraphQLObjectType). Странно то, что он не выдает ошибок, если у BookType есть автор.

user.js (UserType):

const {
    GraphQLList,
    GraphQLID, 
    GraphQLString, 
    GraphQLObjectType,
    GraphQLNonNull,
    GraphQLInt,
     } = require('graphql');

const BookType = require('./book');
const BookSchema = require('../db/models/book');

console.log(BookType);

module.exports = new GraphQLObjectType({
    name: 'User',
    fields: () => ({
        id: { type: new GraphQLNonNull(GraphQLID) },
        name: { type: new GraphQLNonNull(GraphQLString) },
        books: { 
            type: new GraphQLList(BookType),
            resolve(parent, args){
                return BookSchema.find({_id: parent.id});
            }
         }
    })
});

book.js (BookType):

const {
    GraphQLID, 
    GraphQLString, 
    GraphQLObjectType,
    GraphQLNonNull,
    GraphQLInt } = require('graphql');

const UserType = require('./user');
const UserSchema = require('../db/models/user');

console.log(UserType);


module.exports = new GraphQLObjectType({
    name: 'Book',
    fields: () => ({
        id: { type: new GraphQLNonNull(GraphQLID) },
        author: { 
            type: UserType,
            resolve(parent, args){
                return UserSchema.findOne({_id: parent.author});
            }
         },
        title: { type: new GraphQLNonNull(GraphQLString) },
        sites: { type: new GraphQLNonNull(GraphQLInt) }
    })
});

Как видите, я регистрирую BookType и UserType. Как ни странно, при входе в BookType появляется пустой объект.

Выход:

console.log(BookType) --> {}
console.log(UserType) --> User

Вот ошибка:

Error: Expected [object Object] to be a GraphQL type.
    at invariant (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/jsutils/invariant.js:19:11)
    at assertType (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/definition.js:88:43)
    at new GraphQLList (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/definition.js:258:19)
    at fields (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/src/types/user.js:21:19)
    at resolveThunk (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/definition.js:370:40)
    at defineFieldMap (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/definition.js:532:18)
    at GraphQLObjectType.getFields (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/definition.js:506:44)
    at typeMapReducer (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/schema.js:232:38)
    at /media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/schema.js:239:20
    at Array.forEach (<anonymous>)
    at typeMapReducer (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/schema.js:232:51)
    at /media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/schema.js:239:20
    at Array.forEach (<anonymous>)
    at typeMapReducer (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/schema.js:232:51)
    at Array.reduce (<anonymous>)
    at new GraphQLSchema (/media/lorenz/DATA/Privat/Programmieren/JavaScript/NodeJS/bookShop/node_modules/graphql/type/schema.js:122:28)

person Lorenz    schedule 13.04.2018    source источник
comment
здесь вы повторяете много кода. Я бы начал создавать один файл, назову его schema.js. Работайте над разработкой своего RootQuery, экспортируйте его, а затем для UserType и других создайте из них функции. Таким образом, вместо того, чтобы экспортировать GraphQLObjectType для каждого, вы можете просто экспортировать один раз module.exports = new GraphQLSchema({ query: RootQuery });   -  person Daniel    schedule 30.04.2018
comment
Спасибо за вашу помощь! Теперь это работает. знак равно   -  person Lorenz    schedule 02.05.2018


Ответы (1)


здесь вы повторяете много кода. Я бы начал создавать один файл, назову его schema.js.

Работайте над развитием своего RootQuery, вот пример, который может помочь:

const RootQuery = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    user: {
      type: UserType,
      args: { id: { type: GraphQLString } },
      resolve(parentValue, args) {
        return axios
          .get(`http://localhost:3000/users/${args.id}`)
          .then(res => res.data);
      }
    },
    company: {
      type: CompanyType,
      args: { id: { type: GraphQLString } },
      resolve(parentValue, args) {
        return axios
          .get(`http://localhost:3000/companies/${args.id}`)
          .then(res => res.data);
      }
    }
  }
});

экспортируйте это, а затем для UserType и других создайте из них функции. Вот пример этого:

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    id: { type: GraphQLString },
    firstName: { type: GraphQLString },
    age: { type: GraphQLInt },
    company: {
      type: CompanyType,
      resolve(parentValue, args) {
        return axios
          .get(`http://localhost:3000/companies/${parentValue.companyId}`)
          .then(res => res.data);
      }
    }
  })
});

Таким образом, вместо того, чтобы экспортировать GraphQLObjectType для каждого, вы можете просто экспортировать один раз

module.exports = new GraphQLSchema({ query: RootQuery });
person Daniel    schedule 03.05.2018