【问题标题】:Graphql requiring module outside vs inside GraphQLObjectTypeGraphql 需要模块外部与内部 GraphQLObjectType
【发布时间】:2018-02-08 13:23:04
【问题描述】:

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

它运行良好,然后我决定将其拆分为不同的小文件,例如 root_query_type.jsmutation.jsuser_type.jscompany_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') 一起使用。我可能是一个简单的逻辑问题,但它无法找到。请帮帮我。

【问题讨论】:

    标签: javascript node.js graphql graphql-js


    【解决方案1】:

    您看到的行为并非特定于 GraphQL,而是一般的节点。您的模块中存在循环依赖关系,这导致 user_type.js 中的 require 语句解析为 company_type.js 的不完整副本。

    According to the docs,给定两个相互需要的模块(a.jsb.js):

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

    在导出定义中移动 require 语句是一种解决方案。您还可以将您的导出定义高于您的 require 调用以获得相同的效果。 This question 更深入地研究了循环依赖关系,并提供了一些替代解决方案。

    附带说明,这是我建议不要以编程方式声明 GraphQL 架构的原因之一。您可以使用 graphql-toolsgenerate-schema 从 GraphQL 语言文档生成模式。这可以防止您处理潜在的循环依赖关系并产生更具可读性的模式。您也可以轻松地模块化架构;您的类型定义只是字符串,而您的解析器只是对象——两者都可以轻松组合。

    【讨论】:

    • 是的,我现在知道了。感谢您提供链接参考。
    猜你喜欢
    • 2017-11-29
    • 2017-03-22
    • 1970-01-01
    • 2016-05-22
    • 1970-01-01
    • 2014-05-22
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多