我在尝试扩展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]
}
答案 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