我工作的是've run into an issue while trying to extend my API to include a GraphQL endpoint. The application I'是一种有 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]
}
3 回答
为了防止其他人在这里想知道如何在graphql-js中执行递归类型,在graphql-js的代码中有一个有用的提示:
https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L274
看起来
parent
字段应该在type Comment
下,而不是DefaultMessage
. 这仍然不会阻止parent - comments - parent
查询,但如果您因DDOS原因而担心这一点,那么很多其他类型的请求难以计算,即使使用REST API也是如此,您应该采取其他措施来检测这样的问题 . 攻击 .递归节点
但是,您使用嵌套注释提出了一个非常有趣的问题 . 您如何知道在查询中嵌套
comment
以获取所有嵌套响应需要多少次?我目前无法使用GraphQL来指定递归对象 .我可能会通过从最后一个注释开始逐个获取每个嵌套注释(或者一次获取X个级别)来解决这个限制
node
其次是
我想你有一个
depth
数据结构的depth
属性,这应该非常有用,例如,限制用户发布评论时的最大嵌套深度 .这样你的问题可以这样解决:在
comments
属性的resolver
中,检查depth
,如果depth
非法,则不返回任何内容,否则返回注释并返回 .