本文介绍了GraphQL循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对javascript很新,目前正在学习使用Node.js实现带有MongoDB后端的graphQL API。我遇到了两种类型之间循环依赖的问题。

I am fairly new to javascript and am currently learning to implement a graphQL API with a MongoDB backend using Node.js. I am running into a problem with a circular dependency between two types.

基本上,我有一个经典的博客帖子/博客作者情况。帖子只有一个作者,因此mongoose模式包含对该作者的引用。

Basically, I have a classic blog post/blog author situation. A post only has one author and therefore the mongoose schema holds a reference to that author.

在我的graphQL类型作者中我想添加一个字段posts允许我从作者导航到他们写的所有帖子。引用不是在数据库模型中编码,而是通过控制器检索。这是我的博客邮政编码。

In my graphQL type "Author" I want to add a field "posts" which allows me to navigate from authors to all the posts they have written. The reference is not coded in the database models but retrieved through the controllers. Here's my blog post code.

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文件只导出函数来寻址控制器。

The resolvers.js file only exports functions to address the controllers.

我的作者类型定义如下:

My authors type is defined as follows:

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. 我使用函数返回fields字段。我认为这被称为thunk或闭包。

  2. 我需要函数中的PostType返回字段。当我需要文件./post和其他要求时,错误已经被抛到文件的顶部。

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

when i try to run this server example, i recieve the error:

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

指向该行

type: new graphql.GraphQLList(PostType)

包含上面公布的类型定义的文件也会导出如下查询:

The files containing the type definitions posted above also export queries like this:

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
    }
};

分别为作者。所有东西都集中在这样的Schema文件中:

for the author respectively. Everything is brought together in a Schema file like this:

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的引用,那么服务器启动没有问题。非常感谢任何帮助。

I really don't see any way to resolve this circular dependency. If i simply comment out the references to the PostType in the AuthorType definitions, The server starts without problems. Any help here would be greatly appreciated.

也许是为了更好地理解。目录结构如下所示:

Maybe for better understanding. The directory structure looks like this:

│   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


推荐答案

这是模块循环依赖的典型问题 - 你可以参考这个问题。在这种情况下,它与GraphQL无关。

This is rather typical problem of modules circular dependency - you can refer to this question How to deal with cyclic dependencies in Node.js. In this case it has nothing to do with GraphQL.

此外,你做 module.exports = {PostType} 但是在 AuthorType 中你执行 var PostType = require('./ post'),不应该是 var PostType = require('。/ post')。PostType ?我想这是你得到以下错误的原因:

What is more, you do module.exports = { PostType } however in AuthorType you perform var PostType = require('./post'), shouldn't that be var PostType = require('./post').PostType? I suppose this is the cause of below error you get:

只能创建一个GraphQLType的List但得到:[object Object]。

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

Because your PostType is now { PostType: ... } and not a GraphQLObjectType instance.

这篇关于GraphQL循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 07:08