Graphql requiring module outside vs inside GraphQLObjectType

天大地大妈咪最大 提交于 2019-12-12 18:04:04

问题


May be the title is not suitable with my problem but let me explain my scenario. I am working with Graphql schema.Here is my initial schema.js file https://github.com/sany2k8/graphql-udemy/blob/master/schema/schema.js

and it was working fine then I decided to split it into different small files e.g root_query_type.js, mutation.js, user_type.js and company_type.js. All the files are exported as module and required circularly. For example -

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;

On my user_type.js file when I use const CompanyType = require('./company_type'); at the top of file like this const UserType it is showing me below error message

Error: User.company field type must be Output Type but got: [object Object].

but if I comment out that line and put it directly then it works.

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

So basically my question is why it is not working with const CompanyType = require('./company_type'); and but working withtype: require('./company_type'). I could be a simple logical issue but It couldn't able to find.Please help me out.


回答1:


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 require statement inside user_type.js to resolve to an incomplete copy of company_type.js.

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

When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module. b.js then finishes loading, and its exports object is provided to the a.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 graphql-tools'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.



来源:https://stackoverflow.com/questions/45967015/graphql-requiring-module-outside-vs-inside-graphqlobjecttype

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!