Graphql需要外部模块与内部GraphQLObjectType [英] Graphql requiring module outside vs inside GraphQLObjectType

查看:142
本文介绍了Graphql需要外部模块与内部GraphQLObjectType的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题可能不适合我的问题,但请允许我解释一下我的情况. 我正在使用Graphql模式.这是我的初始schema.js文件 https://github.com/sany2k8/graphql-udemy/blob/master/schema/schema.js

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

一切正常,然后我决定将其拆分为不同的小文件,例如 root_query_type.js mutation.js user_type.js >和 company_type.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;

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

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

错误:User.company字段类型必须为Output Type,但得到:[object 对象].

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

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

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.

推荐答案

您看到的行为并非特定于GraphQL,而是通常为node.您的模块中具有循环依赖性,这导致user_type.js中的require语句解析为company_type.js的不完整副本.

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.

根据文档,给出了两个模块(a.js)彼此需要:

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

main.js加载a.js时,然后a.js依次加载b.js.在那时候, b.js尝试加载a.js.为了防止无限循环, a.js导出对象的未完成副本返回到b.js 模块. b.js然后完成加载,并提供其exports对象 到a.js模块.

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.

在导出定义内移动require语句是一种解决方案.您还可以将您的出口定义移动到 上方,以产生相同的影响. 此问题更深入地探讨了循环依赖还提供了一些替代解决方案.

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.

作为旁注,这是我建议不要以编程方式声明GraphQL模式的原因之一.您可以使用graphql-tools generate-schema 来从GraphQL语言文档生成模式.这样可以防止您处理潜在的循环依赖性,并导致更易读的架构.您还可以轻松地将模式模块化.您的类型定义仅是字符串,而解析程序仅是对象-两者都可以轻松组合.

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.

这篇关于Graphql需要外部模块与内部GraphQLObjectType的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆