Graphql Schema 类型错误指示重复类型,它没有?

Posted

技术标签:

【中文标题】Graphql Schema 类型错误指示重复类型,它没有?【英文标题】:Graphql Schema type error indicating duplicate types, which it does not have? 【发布时间】:2018-10-26 15:15:02 【问题描述】:

我现在完全浪费了我的晚上试图解决这个问题,但即使经过多次搜索,我也无法找到答案。

我有我的服务器,它抓取我的“.graphql”文件文件夹并将它们合并成一个大文件夹,我将其与解析器一起传递到“makeExecutableSchema()”中,如下所示

        const folders      = fs.readdirSync(path.join(__dirname, './api'));
        const allResolvers = [];
        let typeDefs       = '';

        folders.forEach(folder => 
          if (folder !== 'directive') 
            typeDefs = typeDefs.concat(requireText(`./api/$folder/$folder.graphql`, require));
            const  resolver  = require(`./api/$folder/$folder.resolvers`);
            allResolvers.push(resolver);
          
        );

        const resolvers = _.merge(allResolvers);
        return makeExecutableSchema(typeDefs, resolvers);

现在我经常收到错误

    Error: Schema must contain unique named types but contains multiple types named "Address".
        at invariant (C:\100hotwater\src\server\node_modules\graphql\jsutils\invariant.js:19:11)
        at typeMapReducer (C:\100hotwater\src\server\node_modules\graphql\type\schema.js:216:58)
        at Array.reduce (<anonymous>)
        at C:\100hotwater\src\server\node_modules\graphql\type\schema.js:237:36
        at Array.forEach (<anonymous>)
        at typeMapReducer (C:\100hotwater\src\server\node_modules\graphql\type\schema.js:232:51)
        at Array.reduce (<anonymous>)
        at new GraphQLSchema (C:\100hotwater\src\server\node_modules\graphql\type\schema.js:122:28)
        at Object.extendSchema (C:\100hotwater\src\server\node_modules\graphql\utilities\extendSchema.js:161:10)
        at buildSchemaFromTypeDefinitions (C:\100hotwater\src\server\node_modules\graphql-tools\dist\schemaGenerator.js:186:28)
        at _generateSchema (C:\100hotwater\src\server\node_modules\graphql-tools\dist\schemaGenerator.js:97:18)
        at Object.makeExecutableSchema (C:\100hotwater\src\server\node_modules\graphql-tools\dist\schemaGenerator.js:110:20)
        at Object.exports.allSchema (C:\100hotwater\src\server\helpers.js:22:28)
        at Server.graphQl (C:\100hotwater\src\server\index.js:28:34)
        at new Server (C:\100hotwater\src\server\index.js:17:14)
        at Object.<anonymous> (C:\100hotwater\src\server\index.js:42:19)

这个模式绝对不包含重复项,尽管如下所示,它在进入“makeExecutableSchema”()”函数之前打印出来。

      type Lead 
        _id: String
        owner: User
        address: Address
        steps: [Step]
      

      type Mutation 
        createLead(
          owner: String!
          address: Address
          steps: [Step]
        ): Lead
      

      type Address 
        lat: Int
        lng: Int
        formattedAddress: String
      

      type Step 
        goto: String
        key: String
        str: String
      

      type User 
        _id: String
        email: String
        firstName: String
        lastName: String
        mobile: Int
        phone: Int
        billingAddress: String
        password: String
        leads: [Lead]
      

      type Query 
        signedInUser: User
        userByEmail(email: String!): User # @isAuthenticated
      

      extend type Mutation 
        signIn(email: String!, password: String!): SignInResponse!
        createUser(
          email: String!
          firstName: String!
          lastName: String
          mobile: Int
          billingAddress: String
          password: String
        ): User
      

      type SignInResponse 
        token: String
        refreshToken: String
      

我在文件“node_modules\graphql\type\schema.js:216:58”中注意到它似乎循环输入两次,显然在检查中两次捕获地址并发布错误,但我仍然不确定从这往哪儿走。 Graphql 中这样的简单错误让人很难爱上它。

感谢任何帮助。

修复

简而言之,感谢下面的 Dan,我正在定义地址类型并将其用于我的输入(突变)和输出(查询 - 线索)。我当时没有意识到您需要以不同的方式定义类型和输入。下面的工作 .graphql 架构。

      type Lead 
        _id: String
        owner: User
        address: Address
        steps: [Step]
      

      type Address 
        lat: Int
        lng: Int
        formattedAddress: String
      

      type Mutation 
        createLead(
          owner: String!
          address: AddressInput 
          steps: [Step]
        ): Lead
      

      input AddressInput 
        lat: Int
        lng: Int
        formattedAddress: String
      

【问题讨论】:

【参考方案1】:

我不确定您的解析器模块是什么样的,但我怀疑您打算这样做:

const resolvers = _.merge(...allResolvers) // note the spread operator

否则,调用merge 实际上并没有做任何事情,您的resolvers 属性最终会成为一个数组而不是一个对象。

编辑:第一眼没注意到,但您使用类型作为输入。如果要使用与Address 类型具有相同形状的对象,则必须为其定义单独的输入类型:

type Address 
  lat: Int
  lng: Int
  formattedAddress: String


input AddressInput 
  lat: Int
  lng: Int
  formattedAddress: String

类型不能用于输入,输入也不能用于类型。如果我们以编程方式定义模式,我们通常会看到一个错误。显然,从 SDL 生成架构不会产生相同的错误。如果您为 Address 和 Step 添加适当的输入类型,您的架构应该会正确生成。

【讨论】:

谢谢,Daniel 这实际上是一个问题,并且刚刚修复,但不幸的是,多类型问题仍然存在。 @22Ryann 奇数。你有可以分享的回购链接吗?如果不查看更多底层代码,很难知道会发生什么。 在 src/server/src/helpers.ts 中 丹尼尔,感谢您抽出宝贵时间。今晚我会更深入地研究并更改我的文件。我实际上是在回顾我在不同情况下使用类型的其他一些代码,它似乎显然工作错误。如果您不介意,我会尝试并可能发布它以尝试了解您的看法 现在得到这个丹尼尔,试图创建新的潜在客户,“Lead.address 的类型必须是输出类型,但得到:AddressInput。”

以上是关于Graphql Schema 类型错误指示重复类型,它没有?的主要内容,如果未能解决你的问题,请参考以下文章

处理混合类型的 GraphQL Schema

如何使用 Mongoose Schema 修复 GraphQL Mutation 中的构造函数错误 [重复]

我无法在 typeDefs 中导入 schema.graphql 文件:找不到以下指针的任何 GraphQL 类型定义:

GraphQL Schema 定义语言中的别名类型

无法在 GraphQL Schema 中嵌套类型

GraphQL/Relay Schema 无法在“CreateLinkPayload”类型上查询字段“store”