本指南说明如何从已弃用(且即将下线)的 zone analytics API 迁移到 GraphQL API。它以 colos 端点的一个合理用例为例,然后展示该用例如何转换为 GraphQL API 查询。本指南还探讨了 GraphQL API 相比其所替代 API 更强大的功能。
在此示例中,我们希望计算特定 colo 的请求数量,并按请求发生的小时进行细分。参考 zone analytics colos 端点,我们可以构造 curl 命令从 API 检索数据。
curl -H "Authorization: Bearer $API_TOKEN" "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/analytics/colos?since=2020-12-10T00:00:00Z" > colos_endpoint_output.json此查询表示:
- 给定对
ZONE_ID具有 Analytics 读取权限的API_TOKEN。 - 获取
ZONE_ID的 colos 分析数据,时间范围从2020-12-10T00:00:00Z(since参数)到现在。
我们要回答的问题是:"ZHR 每小时有多少请求?" 使用 colos 端点响应数据和 jq 处理后,可以用以下命令回答该问题:
cat colos_endpoint_output.json | jq -c '.result[] | {colo_id: .colo_id, timeseries: .timeseries[]} | {colo_id: .colo_id, timeslot: .timeseries.since, requests: .timeseries.requests.all, bandwidth: .timeseries.bandwidth.all} | select(.requests > 0) | select(.colo_id == "ZRH") '此 jq 命令较复杂,我们可以逐步分解:
.result[]这表示将 result 数组拆分为单独的 JSON 行。
{colo_id: .colo_id, timeseries: .timeseries[]}这会将每条 JSON 行拆分为多条 JSON 行。每条结果行包含一个 colo_id 和 timeseries 数组中的一个元素。
{colo_id: .colo_id, timeslot: .timeseries.since, requests: .timeseries.requests.all, bandwidth: .timeseries.bandwidth.all}这会扁平化每行 timeseries 对象中我们感兴趣的数据。
select(.requests > 0) | select(.colo_id == "ZRH")这仅选择请求数大于 0 且 colo_id 为 ZRH 的行。
最终数据如下所示:
Response
{"colo_id":"ZRH","timeslot":"2020-12-10T00:00:00Z","requests":601,"bandwidth":683581}
{"colo_id":"ZRH","timeslot":"2020-12-10T01:00:00Z","requests":484,"bandwidth":550936}
{"colo_id":"ZRH","timeslot":"2020-12-10T02:00:00Z","requests":326,"bandwidth":370627}
{"colo_id":"ZRH","timeslot":"2020-12-10T03:00:00Z","requests":354,"bandwidth":402527}
{"colo_id":"ZRH","timeslot":"2020-12-10T04:00:00Z","requests":446,"bandwidth":507234}
{"colo_id":"ZRH","timeslot":"2020-12-10T05:00:00Z","requests":692,"bandwidth":787688}
{"colo_id":"ZRH","timeslot":"2020-12-10T06:00:00Z","requests":1474,"bandwidth":1676166}
{"colo_id":"ZRH","timeslot":"2020-12-10T07:00:00Z","requests":2839,"bandwidth":3226871}
{"colo_id":"ZRH","timeslot":"2020-12-10T08:00:00Z","requests":2953,"bandwidth":3358487}
{"colo_id":"ZRH","timeslot":"2020-12-10T09:00:00Z","requests":2550,"bandwidth":2901823}
{"colo_id":"ZRH","timeslot":"2020-12-10T10:00:00Z","requests":2203,"bandwidth":2504615}
...如何使用 GraphQL API 获得相同结果?
GraphQL API 允许我们更精确地指定要检索的数据。colos 端点强制我们检索每个 colo 的请求和带宽细分信息,而 GraphQL API 允许我们只获取感兴趣的信息。
我们需要的数据与 HTTP 请求有关。因此,我们使用 HTTP 请求数据的规范来源,即 httpRequestsAdaptiveGroups。GraphQL API 中的此节点允许您按几乎任何可想象的 HTTP 请求维度进行筛选和分组。它是 Adaptive 的,因此响应会很快,因为它由我们的 ABR 技术 ↗ 驱动。
以下是 GraphQL API 查询,用于检索回答"ZHR 每小时有多少请求?"所需的数据:
{
viewer {
zones(filter: {zoneTag:"$ZONE_TAG"}) {
httpRequestsAdaptiveGroups(filter: {datetime_gt: "2020-12-10T00:00:00Z", coloCode:"ZRH"}, limit:10000, orderBy: [datetimeHour_ASC]) {
count
sum {
edgeResponseBytes
}
avg {
sampleInterval
}
count
dimensions {
datetimeHour
coloCode
}
}
}
}
}然后可以用 curl 运行:
curl -X POST -H "Authorization: Bearer $API_TOKEN" https://api.cloudflare.com/client/v4/graphql -d "@./coloGroups.json" > graphqlColoGroupsResponse.json我们可以像之前一样使用 jq 回答问题:
cat graphqlColoGroupsResponse.json| jq -c '.data.viewer.zones[] | .httpRequestsAdaptiveGroups[] | {colo_id: .dimensions.coloCode, timeslot: .dimensions.datetimeHour, requests: .count, bandwidth: .sum.edgeResponseBytes}'此命令比之前简单得多,因为 GraphQL API 返回的数据比 colos 端点更具体。
尽管如此,仍值得解释该命令,因为它有助于理解 GraphQL API 背后的一些概念。
.data.viewer.zones[]GraphQL 响应的格式与查询非常相似。成功的响应始终包含包装响应数据的 data 对象。查询始终有表示用户的 viewer 对象。然后,我们将 zones 对象逐行展开。我们的查询只有一个 zone(因为我们选择了这种方式)。但查询也可以包含多个 zone。
.httpRequestsAdaptiveGroups[]httpRequestsAdaptiveGroups 字段是一个列表,列表中每个数据点代表所选维度的组合,以及该维度组合所选聚合的结果。这里,我们将每个数据点逐行展开。
{colo_id: .dimensions.coloCode, timeslot: .dimensions.datetimeHour, requests: .count, bandwidth: .sum.edgeResponseBytes}这很直观:它只是以 colos 端点之前使用的格式,选择每个数据点中我们感兴趣的属性。
GraphQL API 是非常强大的工具,您可以按许多维度筛选和分组数据。Zone Analytics API 的 colos 端点完全不具备此功能。