我正在研究我的第一个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)
是否有某些方法可以获得更好的错误消息,因此我可以缩小实际问题的范围?
答案 0 :(得分:1)
GraphQLList
和GraphQLNonNull
是包装类型,这意味着它们总是必须按如下方式创建:
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