【问题标题】:Dynamically creating graphql schema with circular references使用循环引用动态创建 graphql 模式
【发布时间】:2017-01-08 11:26:52
【问题描述】:

通过使用graphql-js,我需要通过迭代一些数据数组来动态创建graphql模式,例如:

[{
    name: 'author',
    fields: [{
        field: 'name'
    }, {
        field: 'books',
        reference: 'book'
    }]
}, {
    name: 'book',
    fields: [{
        field: 'title'
    }, {
        field: 'author',
        reference: 'author'
    }]
}]

问题是循环引用。当我创建 AuthorType 时,我需要已经创建 BookType,反之亦然。

因此生成的架构应该如下所示:

type Author : Object {  
  id: ID!
  name: String,
  books: [Book]
}

type Book : Object {  
  id: ID!
  title: String
  author: Author
}

我该如何解决这个问题?

【问题讨论】:

标签: graphql circular-dependency graphql-js circular-reference


【解决方案1】:

我通过对 fields 字段使用 thunk 解决了这个问题。

const User = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    id: { type: GraphQLID }
  })
});

当您将字段设置为 thunk 而不是对象字面量时,您可以使用稍后在文件中定义的类型。

请参阅此帖子以获取更多信息Is there a way to avoid circular type dependencies in GraqhQL?

根据那篇帖子,我认为这是正确的做法。

【讨论】:

    【解决方案2】:

    引用自官方文档

    http://graphql.org/docs/api-reference-type-system/

    当两个类型需要相互引用,或者一个类型需要引用时 在一个字段中,你可以使用一个函数表达式(又名闭包 或 thunk) 懒惰地提供字段。

    var AddressType = new GraphQLObjectType({
      name: 'Address',
      fields: {
        street: { type: GraphQLString },
        number: { type: GraphQLInt },
        formatted: {
          type: GraphQLString,
          resolve(obj) {
            return obj.number + ' ' + obj.street
          }
        }
      }
    });
    
    var PersonType = new GraphQLObjectType({
      name: 'Person',
      fields: () => ({
        name: { type: GraphQLString },
        bestFriend: { type: PersonType },
      })
    });
    

    另请查看循环类别-子类别类型的相关answer

    【讨论】:

    • 这个答案几乎是正确的,确实必须使用函数表达式。此外,您必须对数据进行两次迭代。在第一次迭代中,您将创建所有类型,但 fields 函数返回空对象上的链接。在第二文字中,您需要用实际数据填充这些空对象
    猜你喜欢
    • 2019-09-11
    • 2019-05-20
    • 2022-06-24
    • 2014-03-31
    • 2018-04-10
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多