Worker 内から Analytics Engine のデータにアクセスするには、fetch で SQL API を呼び出します。API は JSON を返すため、JavaScript から扱いやすいです。
Worker が API に認証するには、アカウント ID と API トークンが必要です。
- 32 文字のアカウント ID は、Cloudflare ダッシュボードから取得できます。
- API トークンもダッシュボードで作成できます。詳細は SQL API のドキュメント を参照してください。
アカウント ID は環境変数、API トークンはシークレットとして Worker に保存することをおすすめします。設定はダッシュボードまたは 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 はシークレットとして設定できます。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>`;
}