【问题标题】:GraphQL: One of the provided types for building the Schema is missing a nameGraphQL:为构建模式提供的一种类型缺少名称
【发布时间】:2020-07-30 06:09:43
【问题描述】:

我正在学习 GraphQL,所以遇到了一个奇怪的问题

我在一个文件 Schema.js 中有这段代码:

const graphQL = require('graphql');
const lodash = require('lodash')
const { GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLID, GraphQLSchema, GraphQLList } = graphQL;

const StatusType = new GraphQLObjectType({
name: 'Status',
fields: () => ({
    id: { type: GraphQLInt },
    statusName: { type: GraphQLString },
    user: {
        type: new GraphQLList(UserType),
        resolve(parentValue, args){
            
        }
    }
})
});

const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
    id: { type: GraphQLString },
    username: { type: GraphQLString },
    mail: { type: GraphQLString },
    password: { type: GraphQLString },
    status: { 
        type: StatusType,
        resolve(parentValue, args){
            
        }
    },
})
});

const RouteQuery = new GraphQLObjectType({
name: 'RouteQuery',
user: {
        type: UserType,
        args: { id: { type: GraphQLString } },
        resolve(parentValue, args){
            //return lodash.find(users, { id: args.id })
        }
    },
userSome: {
        type: new GraphQLList(UserType),
        args: { id: { type: GraphQLString } },
        resolve(parentValue, args){
            if (args.id) {
                //return users.filter(user => user.id === args.id);
            }
            //return users;
        }
    },
userAll: {
        type: new GraphQLList(UserType),
        resolve(parentValue){
            //return users
        }
    },
status:{
        type: StatusType,
        args: { id: { type: GraphQLInt } },
        resolve(parentValue, args){
            //return lodash.find(status, { id: args.id })
        }
    },
statusAll: {
        type: new GraphQLList(StatusType),
        resolve(parentValue){
            //return users
        }
    }
    }
});

module.exports = new GraphQLSchema({
query: RouteQuery
})

此代码运行成功,但是当我尝试将它们分成多个文件时:const StatusType & UserType 如下例所示: StatusType 在 StatusType.js 文件上,而 UserType 在 UserType.js 文件上

StatuType.js 文件:

const graphQL = require('graphql');
const { GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLID, GraphQLSchema, GraphQLList } = graphQL;
const UserType = require('./UserType')
const StatusType = new GraphQLObjectType({
name: 'Status',
fields: () => ({
    id: { type: GraphQLInt },
    statusName: { type: GraphQLString },
    user: {
        type: new GraphQLList(UserType),
        resolve(parentValue, args){
            //return users.filter(user => user.status === parentValue.id);
        }
    }
})
});
module.exports = StatusType;

UserType.js 文件:

const graphQL = require('graphql');
const { GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLID, GraphQLSchema, GraphQLList } = graphQL;
const StatusType = require('./StatusType')

const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
    id: { type: GraphQLString },
    username: { type: GraphQLString },
    mail: { type: GraphQLString },
    password: { type: GraphQLString },
    status: { 
        type: StatusType,
        resolve(parentValue, args){
            //return lodash.find(status, { id: parentValue.status })
        }
    },
})
});
module.exports = UserType;

在 Schema.js 文件中,我像这样包含这两个:

const StatusType = require('./StatusType');
const UserType = require('./UserType');

所以我没有将所有代码放在同一个文件中,而是将 StatusType 和 UserType 放在各自的文件中。

但是当我运行这段代码时,我得到了这个错误:

所以我不知道这里有什么问题:/

但是当我尝试 console.log const UserType = require('./UserType') 时,我得到了 User 作为响应:o 就像它在 Schema.js 上的相同代码上时一样

【问题讨论】:

    标签: javascript node.js graphql node-modules


    【解决方案1】:

    你在 nodeJs 处理require 的方式上遇到了问题。请参阅http://nodejs.org/api/modules.html#modules_cycles 了解如何在节点中处理require

    特别是在你的情况下,当你这样做时:

    const StatusType = require('./StatusType');
    const UserType = require('./UserType');
    
    1. StatusTypeconst StatusType = require('./StatusType'); 加载
    2. StatusType.jsconst UserType = require('./UserType') 加载 UserType
    3. UserType.js 应该需要 StatusType 但 nodeJs 会阻止这种情况以避免无限循环。结果,它执行下一行
    4. UserType 初始化为 new GraphQLObjectType(...) 并将 fields 定义为函数。函数闭包手上一个变量StatusType 尚未初始化。这只是一个空的导出模块{}

    您可以验证在创建UserType 字段时添加console.log(StatusType);

    const UserType = new GraphQLObjectType({
      name: 'User',
      fields: () => {
        console.log(StatusType);
        return ({
          id: { type: GraphQLString },
          username: { type: GraphQLString },
          mail: { type: GraphQLString },
          password: { type: GraphQLString },
          status: {
            type: StatusType,
            resolve(parentValue, args) {
    
            }
          },
        });
      }
    });
    

    你会得到:

    {} //instead of StatusType
    

    当所有内容都在同一个文件中时,您不会遇到此问题,因为 UserTypeStatusType 都在同一个闭包中定义,现在又相互定义。

    要解决这个问题,您必须在同一级别上定义 UserTypeStatusType 并注入它们。 here 是一个很好的例子。在你的情况下:

    // StatusType.js
    const StatusType = (types) => new GraphQLObjectType({
      name: 'Status',
      fields: () => {
        console.log(types.UserType);
        return ({
          id: { type: GraphQLInt },
          statusName: { type: GraphQLString },
          user: {
            type: new GraphQLList(types.UserType),
            resolve(parentValue, args) {
    
            }
          }
        });
      }
    });
    
    module.exports = StatusType;
    
    // UserType.js
    const UserType = (types) => new GraphQLObjectType({
      name: 'User',
      fields: () => {
        console.log(types.StatusType);
        return ({
          id: { type: GraphQLString },
          username: { type: GraphQLString },
          mail: { type: GraphQLString },
          password: { type: GraphQLString },
          status: {
            type: types.StatusType,
            resolve(parentValue, args) {
    
            }
          },
        });
      }
    });
    module.exports = UserType;
    
    // Schema.js
    const StatusTypeInject = require('./StatusType');
    const UserTypeInject = require('./UserType');
    
    const types = {};
    types.StatusType = StatusTypeInject(types);
    types.UserType = UserTypeInject(types);
    
    const StatusType = types.StatusType;
    const UserType = types.UserType;
    
    

    【讨论】:

      【解决方案2】:

      您可以在此处进行一些清理,这是我解决这些情况的方法:

      [..]
      // import GraphQLNonNull from the graphql lib
      // In your case, I'd use GraphQLID instead of GraphQLString
      
      userSome: {
        type: new GraphQLList(require('../path/to/UserType')),
        args: { id: { type: new GraphQLNonNull(GraphQLID) } },
        resolve: async (parentValue, args) => {
          // No need for the if statement as we'd sure to have an id.
          // return await filter users by id.
        }
      },
      [..]
      

      和往常一样,将您的 fields 保留为函数:fields: () => ({})

      【讨论】:

        【解决方案3】:

        您是在声明之前在 StatusType 中导入 UserType。

        const StatusType = require('./StatusType');
        const UserType = require('./UserType');
        

        【讨论】:

          猜你喜欢
          • 2021-07-22
          • 2020-08-12
          • 1970-01-01
          • 2018-10-23
          • 2021-08-20
          • 1970-01-01
          • 2017-08-04
          • 1970-01-01
          • 2016-01-31
          相关资源
          最近更新 更多