构建GraphQL类型

时间:2015-09-07 16:24:40

标签: graphql

我在尝试扩展API以包含GraphQL端点时遇到了一个问题。我正在处理的应用程序是一种Messages的论坛。消息可以包含Message类型的注释。如果消息是注释,则其父类型为Message。简化后,架构如下所示:

type Message {
  id: String
  content: String
  comments: [Message]
  parent: Message
}

type RootQuery {
  message(id: String): Message
  messages: [Message]
}

此架构的问题在于它允许这样的查询:

{
  messages {
    comments {
      parent {
        comments {
          parent {
            comments {
              parent {
                id
                content       
              }
            }       
          }
        }   
      }
    }
  }
}

请记住,我可能希望允许任意深度嵌套注释。在这种情况下,应允许以下查询:

{
  messages {
    comments {
      comments {
        comments {
          id
          content
        }
      }
    }
  }
}

所以,我的问题是:我应该向不知道其父级的API引入新类型 - 注释吗?或者有没有其他方法来限制这种不受欢迎的行为?

另外,使用Comment类型会禁止我在查询中使用fragment messageFields on Message语法吗?也许现在是将接口引入模式的时候了?

如果我介绍注释类型(我还没试过),建议解决方案:

interface Message {
  id: String
  content: String
  comments: [Message]
}

type DefaultMessage : Message {
  id: String
  content: String
  comments: [Comment]
  parent: Message
}

type Comment : Message {
  id: String
  content: String
  comments: [Message]
}

type RootQuery {
  message(id: String): Message
  messages: [Message]
}

1 个答案:

答案 0 :(得分:3)

以防万一其他人最终想知道如何在graphql-js中执行递归类型,在graphql-js的代码中有一个有用的提示:

 * When two types need to refer to each other, or a type needs to refer to
 * itself in a field, you can use a function expression (aka a closure or a
 * thunk) to supply the fields lazily.
 *
 * Example:
 *
 *     var PersonType = new GraphQLObjectType({
 *       name: 'Person',
 *       fields: () => ({
 *         name: { type: GraphQLString },
 *         bestFriend: { type: PersonType },
 *       })
 *     });
 *
 */

https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L274