Graphql需要模块外部vs GraphQLObjectType内部
可能是标题不适合我的问题,但让我解释我的情况。 我正在使用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字段types必须是输出types,但会得到:[object 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')
。 我可能是一个简单的逻辑问题,但它无法find请帮助我。
你看到的行为不是特定于GraphQL,而是一般的节点。 在模块中有循环依赖关系,这会导致user_type.js
的require
语句parsing为company_type.js
的不完整副本。
根据文档 ,给定两个模块( a.js
和b.js
)需要彼此:
当
main.js
加载a.js
,然后a.js
加载b.js
在这一点上,b.js
尝试加载a.js
为了防止无限循环,将a.js
exports对象的未完成副本返回给b.js
模块。b.js
然后完成加载,并且它的exports
对象被提供给a.js
模块。
在您的导出定义中移动require语句是一个解决scheme。 您还可以将您的导出定义移动到您的require调用上方以获得相同的效果。 这个问题更深入地研究循环依赖,并提供了一些替代解决scheme。
作为一个侧面说明,这是我build议远离以编程方式声明GraphQL架构的原因之一。 您可以使用graphql-tools
的generate- schema从GraphQL语言文档生成模式。 这可以防止您与潜在的循环依赖关系打交道,并产生更具可读性的模式。 您也可以轻松地模块化您的模式; 你的types定义只是string,你的parsing器只是对象 – 两者都可以很容易地组合。