抽象types节点必须在运行时为字段Root.nodeparsing为Objecttypes,值为“\”,接收到“null”。

我正在实施具有反应和中继的searchfunction。 以下是我的schema.js

var { nodeInterface, nodeField } = nodeDefinitions( (globalId) => { var { type, id } = fromGlobalId(globalId); if (type === 'User') { return getUser(id); }else if (type === 'Post') { return getPost(id); }else if (type === 'Setting') { return getSetting(id); } return null; }, (obj) => { if (obj instanceof User) { return userType; }else if (obj instanceof Post) { return postType; }else if (obj instanceof Setting) { return settingType; } return null; } ); var postType = new GraphQLObjectType({ name: 'Post', fields: { _id: { type: new GraphQLNonNull(GraphQLID) }, createdAt: { type: GraphQLString }, id: globalIdField('Post'), title: { type: GraphQLString }, color: { type: GraphQLString }, userId: globalIdField('User'), username: { type: GraphQLString, resolve: (post) => getUserById(post.userId), }, content: { type: GraphQLString }, images: { type: postImageType, description: "Post's main image links" } }, interfaces: [nodeInterface] }); const { connectionType: postConnection, } = connectionDefinitions({name: 'Post', nodeType: postType}); var settingType = new GraphQLObjectType({ name: 'Setting', fields: { _id: { type: new GraphQLNonNull(GraphQLID) }, id: globalIdField('Setting'), amount: { type: GraphQLString }, all_posts: { type: postConnection, args: { ...connectionArgs, query: {type: GraphQLString} }, resolve: (rootValue, args) => connectionFromPromisedArray( getAllPosts(rootValue, args), args ), }, }, interfaces: [nodeInterface] }); var Root = new GraphQLObjectType({ name: 'Root', fields: () => ({ node: nodeField, setting: { type: settingType, args: { ...connectionArgs, currency: {type: GraphQLString} }, resolve: (rootValue, args) => { return getSetting(args.currency).then(function(data){ return data[0]; }).then(null,function(err){ return err; }); } }, }) }); 

以下是我的database.js

 export function getAllPosts(params,args) { let findTitle = {}; let findContent = {}; if (args.query) { findTitle.title = new RegExp(args.query, 'i'); findContent.content = new RegExp(args.query, 'i'); } console.log("getAllPosts",args) return new Promise((resolve, reject) => { Post.find({$or: [findTitle,findContent]}).sort({createdAt: 'descending'}).exec({}, function(err, posts) { if (err) { resolve({}) } else { resolve(posts) } }); }) } 

现在我想通过$查询variables获取所有post所以在我看来我写这样的

 import React, { Component } from 'react'; import Relay from 'react-relay'; class BlogList extends Component { constructor(props) { super(props); this.state = { query: '', }; this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit(){ this.props.relay.setVariables({query: this.state.query}); } render() { return ( <div className="input-group col-md-12"> <input type="text" onChange={this.handleChange.bind(this,"query")} value={this.state.query} name="query" placeholder="Enter Title or content"/><br/> <span className="input-group-btn"> <button type="button" onClick={this.handleSubmit} className="btn btn-info btn-lg"> <i className="glyphicon glyphicon-search"></i> </button> </span> </div> ) } }; export default Relay.createContainer(BlogList, { initialVariables: { query: '' }, fragments: { viewer: () => Relay.QL` fragment on Setting { id, all_posts(first: 10000000,query: $query) { edges { node { id, _id, title, content, createdAt, username, color, images{ full } } } } } `, }, }); 

在我有路线

 const SettingQueries = { viewer: () => Relay.QL`query{ setting(currency: "USD") }`, } export default [{ path: '/', component: App, queries: UserQueries,PostQueries,SettingQueries, indexRoute: { component: IndexBody, }, childRoutes: [ ,{ path: 'settings', component: Setting, queries: SettingQueries, }] }] 

事情正在处理/ graphql as Graphql UI

但是当我从网站search它会产生错误的回应

 { "data": { "node": null }, "errors": [ { "message": "Abstract type Node must resolve to an Object type at runtime for field Root.node with value \"\",received \"null\".", "locations": [ { "line": 2, "column": 3 } ] } ] } 

因为我的网页浏览器发送请求如下 在这里输入图像描述

请build议我缺less什么? 另外如果我需要添加一些额外的信息,请让我知道。

这个问题可能在你的nodeDefinitions()函数中。 首先callback,也叫idFetcher必须返回一个单一的对象。 但是,我在你的定义中看到你返回一个集合

 var { nodeInterface, nodeField } = nodeDefinitions( (globalId) => { var { type, id } = fromGlobalId(globalId); ... }else if (type === 'Post') { return getPosts(); // this should be getPost(id) } ); 

这就是为什么你的下一个callback,称为typeResolver失败,并返回一个null。

 var { nodeInterface, nodeField } = nodeDefinitions( ... (obj) => { ... // here you get Promise/Collection instead of single Post instance, therefore condition failed }else if (obj instanceof Post) { return postType; } return null; } ); 

LordDave的回答揭示了你的代码中的一个问题。 正如你在他的回答中所评论的, all_posts字段不工作。

如果您在数据库代码中使用了mongoose库,则会发现您的查询存在问题:

 Post.find({$or: [findTitle,findContent]}).sort({createdAt: 'descending'}).exec({}, function(err, posts) { if (err) { resolve({}) } else { resolve(posts) } }); 

基于exec文档,将您的查询改为

 return Post.find({$or: [findTitle,findContent]}).sort({createdAt: 'descending'}).exec(function(err, posts) { if (err) { resolve({}) } else { resolve(posts) } }); 

作为exec答复的承诺,你甚至可以做

 return Post.find({$or: [findTitle,findContent]}).sort({createdAt: 'descending'}).exec(); 

最后,我通过创build一个新的types“postList”并定义它如下所示

 var { nodeInterface, nodeField } = nodeDefinitions( (globalId) => { var { type, id } = fromGlobalId(globalId); if (type === 'User') { return getUser(id); }else if (type==='postList') { return getpostList(id); } else{ return null; } }, (obj) => { if (obj instanceof User) { return userType; }else if (obj instanceof postList) { return postListType; }else{ return null; } } ); 

在database.js中

 class postList {} postList.id = "Post_id"; export {postList} export function getpostList(id) { return new postList } 

并在根域下面

 var postListType = new GraphQLObjectType({ name: 'postList', description: 'List of posts', fields: () => ({ id: globalIdField('postList'), posts: { type: postConnection, description: 'List of posts', args: { ...connectionArgs, query: {type: GraphQLString} }, resolve: (_, args) => connectionFromPromisedArray(getAllPosts(_,args), args), }, }), interfaces: [nodeInterface], }); var Root = new GraphQLObjectType({ name: 'Root', fields: () => ({ node: nodeField, postList: { type: postListType, resolve:(rootValue)=> { return getpostList() } }, }) }); 

我遇到了这个问题,当我使用InterfaceType并检查了InterfaceType之前,在我的TypeResolver的if-elseif-else中的专用ObjectType