Graphql需要模块外部与GraphQLObjectType内部

时间:2017-08-30 18:03:45

标签: javascript node.js graphql graphql-js

可能是标题不适合我的问题,但让我解释一下我的情景。 我正在使用Graphql schema.Here是我的初始schema.js文件https://github.com/sany2k8/graphql-udemy/blob/master/schema/schema.js

它工作正常然后我决定将其分成不同的小文件,例如 root_query_type.js mutation.js user_type.js company_type.js 。所有文件都作为模块导出并循环使用。例如 -

user_type.js

const graphql = require('graphql');
const axios = require('axios');
const { GraphQLObjectType, GraphQLString, GraphQLInt } = graphql;
//const CompanyType = require('./company_type'); // *this line causing error*


const UserType = new GraphQLObjectType({
    name: "User",
    fields: () => ({
        id:{ type: GraphQLString},
        firstName:{ type: GraphQLString},
        age:{ type: GraphQLInt},
        company :{
            type: require('./company_type'), // *this line fix the error*
            resolve(parentValue, args){
                return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`)
                    .then(res => res.data)
            }
        }
    })
});

module.exports = UserType;

company_type.js

const graphql = require('graphql');
const axios = require('axios');
const { GraphQLObjectType, GraphQLString, GraphQLList } = graphql;
const UserType = require('./user_type');


const CompanyType = new GraphQLObjectType({
    name: "Company",
    fields: ()=> ({
        id: { type: GraphQLString},
        name: { type: GraphQLString},
        description: { type: GraphQLString},
        users:{
            type: new GraphQLList(UserType),
            resolve(parentValue, args){
                return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`)
                    .then(res => res.data)
            }
        }
    })
});

module.exports = CompanyType;

在我的 user_type.js 文件中,当我在文件顶部使用const CompanyType = require('./company_type');时,就像这个const UserType一样,它显示在下面的错误消息

  

错误:User.company字段类型必须是输出类型,但得到:[object   对象。

但如果我将该行注释掉并直接放入,那么它就可以了。

company :{
                type: require('./company_type'),
                resolve(parentValue, args){
                    return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`)
                        .then(res => res.data)
                }
            }

所以基本上我的问题是为什么它不能与const CompanyType = require('./company_type');合作,而是与type: require('./company_type')合作。我可能是一个简单的逻辑问题,但它无法找到。请帮助我。

1 个答案:

答案 0 :(得分:4)

The behavior you're seeing is not specific to GraphQL, but rather node in general. You have cyclic dependencies in your modules, which is causing your mouse(element, delay, callback) statement inside let x = mouse(video, 5000, function (a) { if (document.webkitIsFullScreen) video.style.cursor = "none"; }); x.toggle(1); addEventListener("mousemove", function () { video.style.cursor = "auto"; }); to resolve to an incomplete copy of let x = mouse(chatBox, (45e3), function (a) { chatBox.send({ text: chatBox.username + " is AFK.", italic: true }); }); x.toggle(1); x.addEventListener("mousemove", function () { chatBox.send({ text: chatBox.username + " is no longer AFK", italic: true }); }); .

According to the docs, given two modules (require and user_type.js) that require each other:

When company_type.js loads a.js, then b.js in turn loads main.js. At that point, a.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the b.js exports object is returned to the b.js module. a.js then finishes loading, and its a.js object is provided to the b.js module.

Moving the require statements inside your exports definition is one solution. You could also move your exports definition above your require calls to get the same affect. This question looks at cyclic dependencies in more depth and also offers some alternative solutions.

As a side note, this is one of the reasons I would recommend moving away from declaring a GraphQL schema programatically. You can use b.js's generate-schema to generate a schema from a GraphQL language document. This prevents you from dealings with potential cycle dependencies and results in a much more readable schema. You can modularize your schema easily as well; your type definitions are just strings and your resolvers are just objects -- both of which can easily be combined.