# GraphQL API

GraphQL API

在前面的章节讲到了使用GraphQL 进行实体的定义。

GraphQL 是一种用于API查询的语言，对 API 中的数据提供了一套易于理解的完整描述，使得客户端能够准确地获得它需要的数据。因而可以用于描述数据实体，也可以用于请求想要的数据，得到结果。子图中的数据实体就是使用 GraphQL 接口定义语言（IDL）来描述和定义。

本节来说明如何在HyperGraph 中使用GraphQL查询数据。

查询

在子图 schema.graphql 中，定义了称为实体的类型。对于每种实体类型，将在顶层查询类型上生成一个实体和实体关联的字段。

例子

查询您在实体定义文件中定义的单个Token实体：

&#x20;`{`

&#x20;`token(id: "1") {`

&#x20;`id`

&#x20;`owner`

&#x20;`}}`

注意：查询单个实体时，id字段是必填字段，并且必须是字符串，一般是地址或者Hash等具有唯一标识作用的值。

查询所有Token实体：

&#x20;`tokens {`

&#x20;`id`

&#x20;`owner`

&#x20;`}}`

排序

查询集合时，可以使用orderBy参数按特定属性进行排序。另外，orderDirection可用于指定排序方向，升序表示升序，降序表示降序。

例子

&#x20;`{`

&#x20;`tokens(orderBy: price, orderDirection: asc) {`

&#x20;`id`

&#x20;`owner`

&#x20;`}}`

分页

查询集合时，可以使用第一个参数从集合的开头进行分页。值得注意的是，默认排序顺序是按ID升序字母和数字顺序排序，而不是按创建时间。

此外，skip参数可用于跳过实体和分页。例如 first：100 显示前100个实体，first：100，skip：100 显示以第100个开始的下100个实体。这跟SQL查询中的 Limit start, number 很像。

查询应避免使用非常大的skip值，因为它们通常速度会很慢。对于检索大量数据，最好根据上一个示例中所示的属性来对实体进行分页。

例子

查询前10个Token：

&#x20;`tokens(first: 10) {`

&#x20;`id`

&#x20;`owner`

&#x20;`}}`

为了查询集合中间的一组实体，可以将skip参数与first参数结合使用，以从集合的开头开始跳过指定数量的实体。

例子

查询10个Token实体，从集合开始偏移10个位置：

&#x20;`tokens(first: 10, skip: 10) {`

&#x20;`id`

&#x20;`owner`

&#x20;`}}`

例子

如果需要检索大量实体，则将查询基于属性并按该属性进行过滤会更有效率。例如，使用以下查询检索大量Token实体的数据：

`{`

&#x20;`query manyTokens($lastID: String) {`

&#x20;`tokens(first: 1000, where: { id_gt: $lastID }) {`

&#x20;`id`

&#x20;`owner`

&#x20;`}`

&#x20;`}}`

第一次，它将发送带有 lastID =“” 的查询，并且对于后续请求，会将lastID 设置为上一个请求中最后一个实体的id属性。与使用增加的skip值相比，此方法的性能要好得多。

筛选

您可以在查询中使用where参数来筛选不同的属性。您可以过滤where参数中的多个值，也就是说在where中设置多个条件。

例子

查询失败的 challenge：

&#x20;`{`

&#x20;`challenges(where: { outcome: "failed" }) {`

&#x20;`challenger`

&#x20;`outcome`

&#x20;`application {`

&#x20;`id`

&#x20;`}`

&#x20;`}}`

您可以使用诸如\_gt，\_lte之类的后缀进行值比较：

例子

&#x20;`{`

&#x20;`applications(where: { deposit_gt: "10000000000" }) {`

&#x20;`id`

&#x20;`whitelisted`

&#x20;`deposit`

&#x20;`}}`

参数后缀的完整列表：

`_not`

`_gt`

`_lt`

`_gte`

`_lte`

`_in`

`_not_in`

`_contains`

`_not_contains`

`_starts_with`

`_ends_with`

`_not_starts_with`

`_not_ends_with`

请注意，某些后缀仅适用于特定类型。例如，布尔仅支持\_not，\_in和\_not\_in。

时间遍历查询

您不仅可以查询最新区块中实体的状态（默认情况下是查最新块），还可以查询过去的任意区块的状态。通过在查询的顶层字段中包含block参数，可以通过其块号或其块哈希来指定进行查询的块。

这样的查询结果不会随时间变化，即，无论执行什么时候，在特定的过去的块中查询都将返回相同的结果，但有一个例外，如果您在非常靠近以太坊开始的块中进行查询，如果该区块不在主链上并且链被重组，结果可能会改变。一旦一个块可以被认为是最终确认的，查询的结果将不会改变。

例子

&#x20;`{`

&#x20;`challenges(block: { number: 8000000 }) {`

&#x20;`challenger`

&#x20;`outcome`

&#x20;`application {`

&#x20;`id`

&#x20;`}`

&#x20;`}}`

该查询将返回challenge实体及其关联的应用程序实体，因为它们在8,000,000块后直接存在。

例子

&#x20;`{`

&#x20;`challenges(block: { hash: "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" }) {`

&#x20;`challenger`

&#x20;`outcome`

&#x20;`application {`

&#x20;`id`

&#x20;`}`

&#x20;`}}`

该查询将返回challenge实体及其关联的应用程序实体，因为它们是在使用给定哈希所对应的块之后直接存在的。
