GraphQl圆形依赖性



我是JavaScript的新手,目前正在学习使用Node.js的MongoDB后端实现GraphQl API。我遇到了两种类型之间循环依赖性的问题。

基本上,我有一个经典的博客文章/博客作者情况。一个帖子只有一位作者,因此猫鼬模式对该作者表示参考。

在我的GraphQl类型"作者"中,我想添加一个字段"帖子",该字段可以使我从作者到他们编写的所有帖子。该引用不是在数据库模型中编码的,而是通过控制器检索的。这是我的博客帖子代码。

var graphql = require("graphql");
var AuthorResolvers = require("../resolvers/author");
var PostResolvers = require("../resolvers/post");
var AuthorType = require("./author").AuthorType;
var PostType = new graphql.GraphQLObjectType({
  name: "PostType",
  fields: {
        _id: {
            type: graphql.GraphQLID
        },
        title: {
            type: graphql.GraphQLString
        },
        author: {
            type: AuthorType,
            description: "Author of this post",
            resolve: (post) => AuthorResolvers.retwArgs(post)
        }
    }
});
module.exports = {PostType};

Resolvers.js文件仅导出功能来解决控制器。

我的作者类型定义如下:

var graphql = require ("graphql");
var AuthorResolvers = require("../resolvers/author");
var PostResolvers = require("../resolvers/post");
var AuthorType = new graphql.GraphQLObjectType({
  name: "AuthorType",
  fields: () => {
        var PostType = require("./post");
        return {
            _id: {
                type: graphql.GraphQLID
            },
            name: {
                type: graphql.GraphQLString
            },
            posts: {
                type: new graphql.GraphQLList(PostType),
                description: "Posts written by this author",
                resolve: (author) => PostResolvers.retwArgs(author)
            }
        }
    }
});

我已经尝试了两件事:

  1. 我使用函数返回字段字段。我认为这称为thunk或封闭。
  2. 我需要返回字段的功能中的postType。当我需要文件./post以及其他要求时,错误已经在文件的顶部丢弃。

当我尝试运行此服务器示例时,我收到错误:

Can only create List of a GraphQLType but got: [object Object].

指向线的哪个

type: new graphql.GraphQLList(PostType)

在作者中。

包含上面发布的类型定义的文件还导出了类似的查询:

var PostQuery = {
    posts: {
        type: new graphql.GraphQLList(PostType),
        description: "Posts of this Blog",
        resolve: PostResolvers.ret
    }
};

对于帖子,喜欢这个

var AuthorQuery = {
    authors: {
        type: new graphql.GraphQLList(AuthorType),
        description: "The authors working on this Blog",
        resolve: AuthorResolvers.ret
    }
};

分别为作者。像这样的架构文件中,一切都聚集在一起:

var graphql = require("graphql");
var Author = require("./types/author").AuthorQuery;
var Post = require("./types/post").PostQuery;
var root_query = new graphql.GraphQLObjectType({  
  name: "root_query",
  fields: {
    posts: Post.posts,
    authors: Author.authors
  }
});
module.exports = new graphql.GraphQLSchema({
  query: root_query
});

最后该服务器:

var graphql = require ('graphql').graphql  
var express = require('express')  
var graphQLHTTP = require('express-graphql')
var Schema = require('./api/schema')
var app = express()
  .use("/", graphQLHTTP(
    {
      schema: Schema,
      pretty: true,
      graphiql: true,
    }
  ))
  .listen(4000, function(err) {
    console.log('Running a GraphQL API server at localhost:4000');
  })

我真的看不到解决这种循环依赖性的任何方法。如果我简单地评论Authortype定义中对PostType的引用,则服务器启动而没有问题。这里的任何帮助将不胜感激。

也许是为了更好地理解。目录结构看起来像这样:

│   package.json
│   server.js
│
├───api
│   │   schema.js
│   │
│   ├───controllers
│   │       author.js
│   │       post.js
│   │
│   ├───models
│   │       author.js
│   │       post.js
│   │
│   ├───resolvers
│   │       author.js
│   │       post.js
│   │
│   └───types
│           author.js
│           post.js
│
└───config
        db.js

piotrbienias的响应使我达到了正确的线程。我以前读过,但不完全理解。在需要上课之前,有必要定义出口。就我而言,我能够这样解决:

module.exports.AuthorType = new graphql.GraphQLObjectType({
  name: "AuthorType",
  fields: () => {
        var PostType = require("./post").PostType;
        return {
            _id: {
                type: graphql.GraphQLID
            },
            name: {
                type: graphql.GraphQLString
            },
            posts: {
                type: new graphql.GraphQLList(PostType),
                description: "Posts written by this author",
                resolve: (author) => PostResolvers.retwArgs(author)
            }
        }
    }
});

,类似于后类型。这样,在调用要求之前定义导出。

非常感谢!

这是模块循环依赖性的典型问题 - 您可以参考此问题如何处理node.js中的循环依赖关系。在这种情况下,它与GraphQl无关。

还有什么,您要执行module.exports = { PostType },但是在AuthorType中您执行var PostType = require('./post'),那不是var PostType = require('./post').PostType吗?我想这是您遇到的以下错误的原因:

Can only create List of a GraphQLType but got: [object Object].

因为您的PostType现在是{ PostType: ... },而不是GraphQLObjectType实例。

根据本文GraphQl会在循环依赖性方面增加问题。本文建议使用extend type定义相互依赖类型。在我的情况下它起作用。

因此,而不是定义类型的" staightforward"方式:

type User {
    id: ID
    posts: [Post]
}
type Post {
    id: ID
    user: User
}

您应该使用一个方向定义,然后使用extend这样的添加另一个依赖方向:

type User {
    id: ID 
    // no reference to [Post] !
}
type Post {
    id: ID
    user: User // this stays - single direction
}
extend type User {
    posts: [Post]
}

请参阅文章以获取理由和更详细的示例。

最新更新