GraphQL 是否支持服务器端过滤(即在客户端构建类似 WHERE 的查询)?

Does GraphQL support server-side filtering (i.e. building of WHERE-like queries on client side)?

我正在研究在 React.js 客户端应用程序和建立在关系 SQL 数据库之上的服务器应用程序之间使用 GraphQL 的可能性。应在客户端创建一个查询,包括复杂的 SQL 样式的语句,例如:

WHERE Customer.Age BETWEEN 22 AND 25
AND   Order.Status = 'Active'
OR    Product.Name LIKE '%foo%'

这意味着客户端通常应该只接收一小部分记录(例如 10 而不是 10M)。

这个看起来不错的 Phil Sturgeon article 声明了奇怪的事情:

I was hoping GraphQL could help clients define their own scopes, filtering these includes to be the appropriate data themselves, which would help identify the scoped includes the API should add as convenience methods.

It seems like GraphQL doesn't help API developers in this instance, but there does seem to be talk of adding @filter to do this in the future.

以后呢?现在在 GraphQL 中没有过滤?我继续研究并发现 and this amazing interactive Graphcool documentation。这两个示例都使用了一个名为 filter 的特性和一组后缀,例如 _gte:

query combineMovies {
  allMovies(filter: {
    OR: [{
      AND: [{
        releaseDate_gte: "2009"
      }, {
        title_starts_with: "The Dark Knight"
      }]
    }, {
      title: "Inception"
    }]
  }) {
    title
    releaseDate
  }
}

但是,http://graphql.org 处没有对 filter 关键字的规范。 我什至检查了 Relay 文档,但没有找到复杂过滤的好例子(可能是因为我没有 React 经验)。

请说明 GraphQL 构建复杂 SQL 类 WHERE 查询的能力。它是标准的一部分还是只是一个弱支持的辅助功能?

I continued research and have found this SO question and this amazing interactive Graphcool documentation.

谢谢你的美言!我是这篇文章的作者,很高兴它对您有所帮助!我从GraphcoolAPI.

的角度回答你的问题

GraphQL 查询和字段

GraphQL 查询是使用字段构建的。这里我们使用在allMovies字段上定义的id字段:

query allMovies {
  allMovies {
    id
  }
}

我建议阅读 this article 以获取有关 GraphQL 查询术语的更多信息。

查询参数

GraphQL 定义了所谓的 query arguments 可以附加到字段。这些参数为 GraphQL 服务器编码附加信息并影响字段的解析方式。一个常见的例子是 first 查询参数:

query firstMovie {
  allMovies(first: 1) {
    id
  }
}

过滤是规范的一部分还是只是一个附带功能?

让我们进一步调查!

query darkKnightMovies {
  allMovies(filter: {
    title_contains: "Dark Knight"
  }) {
    id
  }
}

在上面的查询中,filterallMovies 字段的参数。如上所示,其语法方面在 GraphQL 规范中定义。然而,GraphQL 没有指定这个参数应该如何改变 allMovies 字段的解析。这仅由 GraphQL 后端中 allMovies 字段的解析器的更改行为决定。

结论

GraphQL 提供所有必要的概念(查询、字段、参数)来支持服务器端过滤。但是,使用这些概念 来编码过滤等特定行为取决于创建 GraphQL API.

的开发人员

Graphql 是一个规范,有不同的客户端和服务器实现,如 Apollo、Graphcool、Relay。您在问题中粘贴的代码是客户端查询,我认为它有点 complex.In 比查询本身更接近查询构建器。

Graphql 查询可以像您喜欢的那样简单或复杂,如果您正在编写自己的服务器,这完全取决于您。

您可以将简单的键值对发送到您的服务器,并在服务器端的解析器函数中构建数据库查询,并将查询提供给数据库以获取数据。或者,您可以在客户端构建格式良好的查询,并直接将这些查询提供给解析器函数中的数据库,甚至无需触及它。我认为 graqhcool 选择了第二种方法。

所以基本上涉及三个步骤:

  1. 客户端发送一些查询,基本上是 GET 或 POST 带有序列化文本的请求,
  2. 服务器上的解析器函数将其拾取并从数据库中获取请求的数据
  3. 和 returns 响应因此解决了请求。

规范可能没有提到过滤,因为它是实现细节(它只是您在 post 请求中使用的参数名称),尽管如此,请阅读分页部分。

对于初学者来说,规范可能有点抽象,所以从像 Apollo Server 这样的实现服务器开始可能是更好的学习 graphql 的更好方法和更简单的方法。