Cloudflare Workers Analytics Engine のデータに対してSQLを発行するWorkersサンプルスクリプト
前回の記事では、Cloudflare Workers Analytics Engine にデータを蓄積させるWorkersスクリプトを作成しました。"Analytics Engine"と名前がついているため、Workersの実行状況解析用にみえますが、実際はWorkersの固定スキーマのRDBが付いており、SQL/GraphQLからデータ操作ができるという優れモノであることをご紹介しました。
今回は前回のサンプルスクリプトを蓄積されたデータを、別のWorkersからSQLで呼び出すサンプルを行います。まずいつも通りHello Worldまでを完了させておきます。
wrangler.toml の環境設定
name = "analytics"
main = "src/index.js"
compatibility_date = "2023-06-04"
analytics_engine_datasets = [
{ binding = "testanalytics" }
]
[vars]
ACCOUNT_ID = "xxxxxxxxxxx"
このように指定しておきます。testanalytics
は前回用いたWorkersからデータが書き込まれているデータセット名です。
[vars]
ACCOUNT_ID = "xxxxxxxxxxx"
はWorkersスクリプトから参照できる、グローバル変数です。これにより、スクリプトの中にアカウントIDを記載しなくても、ACCOUNT_ID
が定数としてセットされています。
wrangler へのクレデンシャル設定
前回の記事では以下のコマンドにAPIトークンをベタ打ちで埋め込んで実行していました。
curl.exe -X POST "https://api.cloudflare.com/client/v4/accounts/<accountID>/analytics_engine/sql" -H "Authorization: Bearer <tokenID>" -d "SELECT blob1 FROM testanalytics"
今回は、Workersスクリプトではデータの読み込みに必要なトークンをwranglerに環境変数としてセットします。
npx wrangler secret put API_TOKEN
を実行すると、
⛅️ wrangler 2.14.0 (update available 3.1.0)
------------------------------------------------------
? Enter a secret value: »
と聞いてきますので、APIトークンを張り付けるとWranglerにそのトークンがセットされます。
これにより、WorkersスクリプトからはAPI_TOKEN
としてAPIトークンを呼び出せます。
Workersのサンプルindex.jsは以下の通りです。
https://developers.cloudflare.com/analytics/analytics-engine/worker-querying/ の内容を少し書き換えています。
export default {
async fetch(request, env) {
// SQL string to be executed.
const query = `SELECT blob1 as edgecode,blob2 as country,blob3 as city,blob4 as prefecture,blob5 as area,double1,double2,double3,index1 FROM testanalytics`;
// 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,
});
// Read the JSON data from the query response and render the data as HTML.
const queryJSON = await queryResponse.json();
let tableRows = '';
for (let i = 0; i < queryJSON.data.length; i++) {
tableRows += `<tr><td>${queryJSON.data[i].edgecode}</td><td>${queryJSON.data[i].country}</td><td>${queryJSON.data[i].city}</td><td>${queryJSON.data[i].prefecture}</td><td>${queryJSON.data[i].area}</td></tr>`;
}
return new Response(
renderResponse(tableRows),
{
headers: {'content-type': 'text/html'},
}
);
}
}
function renderResponse(tableRows) {
return `<!DOCTYPE html>
<html>
<body>
<table>
<tr><th>EdgeCode</th><th>Country</th><th>City</th><th>Prefecture</th><th>Area</th></tr>
${tableRows}
</table>
</body>
<html>`;
}
デプロイが完了すると以下のようにAnalytics Engineのtestanalyticsデータセットに書き込まれている情報が出力されます。
Discussion