如果要从 Worker 内部访问 Analytics Engine 数据,可以使用 fetch 调用 SQL API。该 API 可以返回易于在 JavaScript 中处理的 JSON 数据。
为使 Worker 能够向 API 进行身份验证,您需要账户 ID 和 API 令牌。
- 32 位字符的账户 ID 可从 Cloudflare 仪表板获取。
- API 令牌也可在仪表板中生成。有关更多信息,请参阅 SQL API 文档。
我们建议将账户 ID 存储为环境变量,将 API 令牌存储为 Worker 中的 secret。可通过仪表板或 Wrangler 完成配置。有关详细信息,请参阅 Workers 文档。
使用 JavaScript fetch API 执行查询,如下所示:
const query = "SELECT * FROM my_dataset";
const API = `https://api.cloudflare.com/client/v4/accounts/${env.ACCOUNT_ID}/analytics_engine/sql`;
const response = await fetch(API, {
method: "POST",
headers: {
Authorization: `Bearer ${env.API_TOKEN}`,
},
body: query,
});
const responseJSON = await response.json();数据将以文档 FORMAT 部分描述的格式返回,使您除了数据本身和行数外,还能提取返回列的名称和类型等元信息。
以下是一个示例 Worker,它对天气读数数据集执行查询,并显示每个城市的最低和最高温度。
首先设置账户 ID 和 API 令牌的环境变量。
账户 ID 在 Wrangler 配置文件 中设置:
{
"vars": {
"ACCOUNT_ID": "<account_id>"
}
}[vars]
ACCOUNT_ID = "<account_id>"API_TOKEN 可设置为 secret。使用 wrangler 命令行工具运行以下命令并输入令牌字符串:
npx wrangler secret put API_TOKENWorker 脚本本身执行查询并格式化结果:
export default {
async fetch(request, env) {
// This worker only responds to requests at the root.
if (new URL(request.url).pathname != "/") {
return new Response("Not found", { status: 404 });
}
// SQL string to be executed.
const query = `
SELECT
blob1 AS city,
max(double1) as max_temp,
min(double1) as min_temp
FROM weather
WHERE timestamp > NOW() - INTERVAL '1' DAY
GROUP BY city
ORDER BY city`;
// Build the API endpoint URL and make a POST request with the query string
const API = `https://api.cloudflare.com/client/v4/accounts/${env.ACCOUNT_ID}/analytics_engine/sql`;
const queryResponse = await fetch(API, {
method: "POST",
headers: {
Authorization: `Bearer ${env.API_TOKEN}`,
},
body: query,
});
// The API will return a 200 status code if the query succeeded.
// In case of failure we log the error message and return a failure message.
if (queryResponse.status != 200) {
console.error("Error querying:", await queryResponse.text());
return new Response("An error occurred!", { status: 500 });
}
// Read the JSON data from the query response and render the data as HTML.
const queryJSON = await queryResponse.json();
return new Response(renderResponse(queryJSON.data), {
headers: { "content-type": "text/html" },
});
},
};
// renderCity renders a table row as HTML from a data row.
function renderCity(row) {
return `<tr><td>${row.city}</td><td>${row.min_temp}</td><td>${row.max_temp}</td></tr>`;
}
// renderResponse renders a simple HTML table of results.
function renderResponse(data) {
return `<!DOCTYPE html>
<html>
<body>
<table>
<tr><th>City</th><th>Min Temp</th><th>Max Temp</th></tr>
${data.map(renderCity).join("\n")}
</table>
</body>
<html>`;
}