React / GraphQL:只能创建Nullable GraphQLType的NonNull,但得到' type'

时间:2016-05-29 22:27:32

标签: reactjs graphql

我正在研究我的第一个GraphQL架构。我之前从未这样做过,而且我对我得到的错误感到困惑。例如:

  /Users/lorm/projects/aggregated_centralized_api/node_modules/graphql/jsutils/invariant.js:20
      throw new Error(message);
      ^

  Error: Can only create NonNull of a Nullable GraphQLType but got: function GraphQLList(type) {
      _classCallCheck(this, GraphQLList);

      (0, _jsutilsInvariant2['default'])(isType(type), 'Can only create List of a GraphQLType but got: ' + type + '.');
      this.ofType = type;
    }.
      at invariant (/Users/lorm/projects/aggregated_centralized_api/node_modules/graphql/jsutils/invariant.js:20:11)
      at new GraphQLNonNull (/Users/lorm/projects/aggregated_centralized_api/node_modules/graphql/type/definition.js:761:39)
      at Object.<anonymous> (/Users/lorm/projects/aggregated_centralized_api/server/schema.js:121:19)
      at Module._compile (module.js:413:34)
      at normalLoader (/Users/lorm/projects/aggregated_centralized_api/node_modules/babel-core/lib/api/register/node.js:199:5)
      at Object.require.extensions.(anonymous function) [as .js] (/Users/lorm/projects/aggregated_centralized_api/node_modules/babel-core/lib/api/register/node.js:216:7)
      at Module.load (module.js:357:32)
      at Function.Module._load (module.js:314:12)
      at Module.require (module.js:367:17)
      at require (internal/module.js:16:19)

我的schemaTypes.js文件如下所示:

  export const BookType = new GraphQLObjectType({
      name: 'Book',
      description: 'A Book',
      fields: () => ({
    book_id: {
        type: GraphQLString,
        description: 'UUID for book',
    },
    title: {
        type: GraphQLString,
        description: 'The name of the book',
    },
    author: {
        type: GraphQLList,
        description: 'List of authors, each author an object',
    },
    isbn: {
        type: GraphQLString,
        description: 'The primary way of identifying the book both domestically and internationally',
    },
    agency_price: {
        type: GraphQLFloat,
        description: 'The price set by the agency',
    },
    pub_date: {
        type: GraphQLString,
        description: 'The publication date of the book',
    },
    amazon_rank: {
        type: GraphQLInt,
        description: "The book's current selling rank on Amazon, updated daily",
    },
    reviews: {
        type: GraphQLFloat,
        description: "The book's current average review rating on Amazon, can 1 to 5, accurate to 1 decimal, updated daily",
    },
    book_img: {
        type: GraphQLString,
        description: 'Absolute URL for the image used for the book cover',
    },
    asin: {
        type: GraphQLString,
        description: "Amazon Standard Identification Numbers (ASINs) are unique blocks of 10 letters and/or numbers that identify items",
    },
    publisher: {
        type: GraphQLString,
        description: "The publisher name. There is only one publisher per book.",
    },
    bisacs: {
        type: GraphQLList,
        description: 'A list of Book Industry Standards and Communications subject headings as strings',
    },
    series_name: {
        type: GraphQLString,
        description: "If the book belongs to a series, the name of the series",
    },
    volume: {
        type: GraphQLString,
        description: "If the book is part of a series, this is its location in the sequence",
    },
    formats: {
        type: GraphQLList,
        description: 'Open Road has 20 standard formats',
    },
    keywords: {
        type: GraphQLList,
        description: 'Open Road puts mulitiple keywords (separated by a semi-colon) into the keyword1 field in Firebrand',
    },
    description: {
        type: GraphQLString,
        description: "Open Road's summary of the book",
    },
    campaigns: {
        type: GraphQLList,
        description: "A list full of marketing Campaigns we've done for the author",
    },
    retailers: {
        type: GraphQLList,
        description: 'A list full of Retailers, holding data specific to this book',
    },
    nominations: {
        type: GraphQLList,
        description: 'A list full of nominations to which this book belongs',
    },
    created: {
        type: GraphQLInt,
        description: 'The creation timestamp of this book'
    }
      })
  });

而schema.js看起来部分如下:

  let schema = new GraphQLSchema({
    query: new GraphQLObjectType({
      name: 'RootQueryType',
      fields: {
        book: {
          type: new GraphQLList(BookType),
          resolve: () => ""
        },
        book_retailer_summary: {
          type: BookRetailerSummaryType,
          args: {
            name: {
              description: 'Summary of books sales information, via various retailers',
              type: new GraphQLNonNull(GraphQLString)
            }
          },
          resolve: (root, {name}) => {
            return mongo()
              .then(db => {
                let deferred = Q.defer();

                let collection = db.collection('users');
                collection.find({ name })
                  .toArray((err, docs) => {
                    if (err) {
                      deferred.reject(err);
                      return;
                    }

                    db.close();
                    deferred.resolve(docs.length ? docs[0] : null);
                  });

                return deferred.promise;
              });

          }
        }
      }
    }),

所以我很好奇我犯了什么错误?

[[更新]]

回应helfer的评论我不得不怀疑GraphQLList的这种用法:

  nomination: {
    type: NominationType,
    args: {
      name: {
        description: 'The name of the list of books',
        type: new GraphQLNonNull(GraphQLString)
      },
      books: {
        description: 'The name of the books belonging to this nomination',
        type: new GraphQLNonNull(GraphQLList)
      }
    },

也许不允许这条线?

        type: new GraphQLNonNull(GraphQLList)

是否有某些方法可以获得更好的错误消息,因此我可以缩小实际问题的范围?

1 个答案:

答案 0 :(得分:1)

GraphQLListGraphQLNonNull是包装类型,这意味着它们总是必须按如下方式创建:

const someListType = new GraphQLList(anotherType);
const someNonNullType = new GraphQLNonNull(anotherType);

您的图书类型包含许多字段GraphQLListType而没有实际创建实例(即不调用new并将类型传递给包装)。该错误消息表明您正试图将GraphQLListType包裹在NonNull某处,但由于您没有正确创建列表类型,因此无法正常工作。

顺便说一下,这些模式在Javascript中可能会很长很难阅读,这就是为什么我创建了一个允许你用模式语言编写它们的软件包,因此它更容易阅读:

type Book {
  book_id: String
  title: String
  author: [Author]
  # etc.
}

您可以在此处找到文档:http://docs.apollostack.com/apollo-server/generate-schema.html