使用GraphQL结构构建复杂的数据库查询

时间:2017-08-09 09:35:32

标签: graphql

我想在GraphQL查询中指定内部约束,这将限制最外层查询的结果,作为我正在处理的查询/谓词构建器的一部分。我不确定这是否属于GraphQL的功能范围,但对我来说这是人们想做的事情。

例如,我可能希望显示最近评论过的博客帖子列表:

{
  posts{
    title
    date
    comments(since: $earliestDate){
      body
      date
      author {
        name
      }
    }
  }
}

这种情况的正常行为是将所有博客帖子和仅符合条件的评论带回来。

{
  "posts": [
    { 
      "title": "Post 1",
      "date": "2017-07-31"
      "comments": [
      ]
    },
    { 
      "title": "Post 2",
      "date": "2017-06-10",
      "comments": [
        {
          "body": "Comment text",
          "date": "2017-08-09",
          "author": {
             "name": "Michael"
          }
        }
      ]
    }

  ]
}

但是我希望我的查询能够阻止检索" Post 1"因为它在上个月没有任何评论,但我不确定GraphQL会让事情变得容易。

GraphQL中是否有支持返回此结果的功能?

{
  "posts": [
    { 
      "title": "Post 2",
      "date": "2017-06-10",
      "comments": [
        {
          "body": "Comment text",
          "date": "2017-08-09",
          "author": {
             "name": "Michael"
          }
        }
      ]
    }

  ]
}

1 个答案:

答案 0 :(得分:2)

TL; DR - 通常,您希望字段的行为仅 定义

  • 传递给该字段的参数
  • 正在查询的对象的标识
  • 查询的全局上下文(例如,执行查询的用户的身份)

我认为你所追求的行为并不适合GraphQL。至少正如我所见,GraphQL倾向于将字段视为彼此相对独立(即使它们是嵌套的)。

例如,您不希望传递给子字段的参数更改其父级的行为。同样地,我认为你不会指望子字段的存在缺席来改变其父字符的行为。

完成您所追求的行为的最佳方法是在posts字段中添加一个参数,表明只应返回包含评论的帖子:

{
  posts(withCommentsOnly: true) {
    title
    date
    comments(since: $earliestDate) {
      body
      date
      author {
        name
      }
    }
  }
}

要了解原因,请考虑以下几种情况:

{
  authors {
    id
    posts {
      comments { body }
    }
  }
}

如果此查询具有您描述的行为,则对于每位作者,您只能获得posts,而comments也有{ node(id: "author_id") { ... on Author { posts { title } } } } 。但是想象一下你以后重新查询其中一位作者:

Select ID, Date, Type, TypeID, Active from TableName ORDER BY Date Limit 1

现在你会得到一组不同的帖子吗?这种行为会使人们很难使用标准的GraphQL客户端查询GraphQL模式,因为客户端缓存机制可能无法正确更新其缓存。