🦔

Cloudflare Workers Analytics Engine のデータに対してSQLを発行するWorkersサンプルスクリプト

2023/06/10に公開

前回の記事では、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