メインコンテンツへスキップ
メインコンテンツへスキップ

クエリ API エンドポイントのセットアップ

Query API Endpoints 機能を使用すると、ClickHouse Cloud コンソールで任意の保存済み SQL クエリから、直接 API エンドポイントを作成できます。ClickHouse Cloud サービスにネイティブ ドライバーで接続する必要なく、HTTP 経由で API エンドポイントにアクセスして保存済みクエリを実行できるようになります。

事前準備

先に進む前に、次の準備ができていることを確認してください:

  • 適切な権限を持つ API キー
  • Admin Console ロール

まだ持っていない場合は、このガイドに従って API キーを作成 できます。

最低限必要な権限

API エンドポイントに対してクエリを実行するには、API キーに Member 組織ロールと Query Endpoints サービスアクセスが必要です。データベースロールはエンドポイント作成時に設定されます。

保存済みクエリを作成する

すでに保存済みクエリがある場合は、このステップをスキップできます。

新しいクエリタブを開きます。デモンストレーションのために、約 45 億件のレコードを含む youtube データセット を使用します。 Cloud サービス上にテーブルを作成し、データを挿入するには、「テーブルを作成」セクションの手順に従ってください。

ヒント
行数を LIMIT で制限する

このサンプルデータセットのチュートリアルでは大量のデータ (46.5 億行) を挿入するため、挿入に時間がかかる場合があります。 本ガイドの目的では、LIMIT 句を使用してより少量のデータを挿入することを推奨します。 例えば 1000 万行程度に制限してください。

サンプルクエリとして、ユーザー入力の year パラメータを用いて、動画あたりの平均再生回数が多いアップローダー上位 10 件を返します。

WITH sum(view_count) AS view_sum,
  round(view_sum / num_uploads, 2) AS per_upload
SELECT
  uploader,
  count() AS num_uploads,
  formatReadableQuantity(view_sum) AS total_views,
  formatReadableQuantity(per_upload) AS views_per_video
FROM
  youtube
WHERE
-- 次の行をハイライト
  toYear(upload_date) = {year: UInt16}
GROUP BY uploader
ORDER BY per_upload desc
  LIMIT 10

このクエリには、上記のスニペットでハイライトされているパラメータ (year) が含まれている点に注意してください。 パラメータは、中括弧 { } とパラメータの型を組み合わせて指定できます。 SQL コンソールのクエリエディタは ClickHouse のクエリパラメータ式を自動的に検出し、各パラメータに対応する入力欄を提供します。

クエリが動作することを確認するために、SQL エディタ右側のクエリ変数入力ボックスに 2010 年を指定して、このクエリを実行してみましょう:

サンプルクエリをテストする

次に、クエリを保存します:

サンプルクエリを保存する

保存済みクエリに関する詳細なドキュメントは、「クエリを保存する」セクションを参照してください。

クエリ API エンドポイントの設定

クエリビューから直接、Share ボタンをクリックし、API Endpoint を選択することで Query API エンドポイントを設定できます。 どの API キーがこのエンドポイントへアクセスできるかを指定するよう促されます:

クエリエンドポイントの設定

API キーを選択した後、次の項目を指定します:

  • クエリの実行に使用する Database ロール (Full accessRead only、または Create a custom role)
  • クロスオリジンリソース共有 (CORS) で許可するドメイン

これらのオプションを選択すると、クエリ API エンドポイントが自動的にプロビジョニングされます。

テストリクエストを送信できるよう、curl コマンドの例が表示されます:

エンドポイント用 curl コマンド

利便性のため、インターフェイスに表示される curl コマンドを以下に示します:

curl -H "Content-Type: application/json" -s --user '<key_id>:<key_secret>' '<API-endpoint>?format=JSONEachRow&param_year=<value>'

Query API パラメータ

クエリ内のクエリパラメータは {parameter_name: type} という構文で指定できます。これらのパラメータは自動的に検出され、サンプルリクエストのペイロードには、これらのパラメータを渡すための queryVariables オブジェクトが含まれます。

テストとモニタリング

Query API エンドポイントを作成したら、curl やその他の HTTP クライアントを使用して動作をテストできます:

エンドポイントの curl テスト

最初のリクエストを送信すると、Share ボタンのすぐ右側に新しいボタンが表示されます。これをクリックすると、そのクエリに関するモニタリングデータを含むフライアウトが開きます:

エンドポイントのモニタリング

実装の詳細

このエンドポイントは、保存済みの Query API エンドポイントに対してクエリを実行します。 複数バージョンへの対応、柔軟なレスポンス形式、パラメータ付きクエリ、およびオプションのストリーミングレスポンス(バージョン 2 のみ)をサポートします。

エンドポイント:

GET /query-endpoints/{queryEndpointId}/run
POST /query-endpoints/{queryEndpointId}/run

HTTP メソッド

メソッドユースケースパラメータ
GETパラメータ付きのシンプルなクエリクエリ変数を URL パラメータ(?param_name=value)として渡す
POST複雑なクエリ、またはリクエストボディを使用する場合クエリ変数をリクエストボディ内の queryVariables オブジェクトとして渡す

GET を使用する場合:

  • 入れ子構造の複雑なデータを伴わないシンプルなクエリ
  • パラメータを容易に URL エンコードできる場合
  • HTTP GET のセマンティクスによるキャッシュの利点を得たい場合

POST を使用する場合:

  • 配列、オブジェクト、大きな文字列などの複雑なクエリ変数がある場合
  • セキュリティ/プライバシー上、リクエストボディで送信することが望ましい場合
  • ストリーミングによるファイルアップロードや大容量データを送信する場合

認証

必須: はい
方式: OpenAPI キー/シークレットを使用した Basic 認証
権限: クエリエンドポイントに対して適切な権限

リクエスト設定

URL パラメータ

パラメータ必須説明
queryEndpointIdはい実行するクエリエンドポイントの一意の識別子

クエリパラメータ

ParameterRequiredDescriptionExample
formatNoレスポンス形式(すべての ClickHouse フォーマットに対応)?format=JSONEachRow
param_:nameNoリクエストボディがストリームの場合に使用するクエリ変数。:name を変数名に置き換えます?param_year=2024
request_timeoutNoクエリのタイムアウト(ミリ秒単位、デフォルト: 30000)?request_timeout=60000
:clickhouse_settingNoサポートされている任意の ClickHouse 設定?max_threads=8

ヘッダー

ヘッダー必須説明
x-clickhouse-endpoint-versionいいえエンドポイントのバージョンを指定します1 または 2(省略時は最後に保存されたバージョン)
x-clickhouse-endpoint-upgradeいいえエンドポイントのバージョンをアップグレードします(version ヘッダーと併用)アップグレードする場合は 1

リクエストボディ

パラメーター

ParameterTypeRequiredDescription
queryVariablesobjectNoクエリで使用する変数
formatstringNoレスポンス形式

サポートされるフォーマット

バージョンサポートされるフォーマット
バージョン 2ClickHouse がサポートするすべてのフォーマット
バージョン 1(制限付き)TabSeparated
TabSeparatedWithNames
TabSeparatedWithNamesAndTypes
JSON
JSONEachRow
CSV
CSVWithNames
CSVWithNamesAndTypes

レスポンス

成功

ステータス: 200 OK
クエリは正常に実行されました。

エラーコード

ステータスコード説明
400 Bad Requestリクエストの形式が正しくありません
401 Unauthorized認証情報がないか、権限が不足しています
404 Not Found指定されたクエリエンドポイントが見つかりませんでした

エラー処理のベストプラクティス

  • リクエストに有効な認証情報が含まれていることを確認する
  • 送信前に queryEndpointIdqueryVariables を検証する
  • 適切なエラーメッセージを伴う、堅牢なエラー処理を実装する

エンドポイントバージョンのアップグレード

バージョン 1 からバージョン 2 にアップグレードするには、次のようにします。

  1. x-clickhouse-endpoint-upgrade ヘッダーを 1 に設定してリクエストに含める
  2. x-clickhouse-endpoint-version ヘッダーを 2 に設定してリクエストに含める

これにより、バージョン 2 で提供される次の機能を利用できるようになります。

  • すべての ClickHouse フォーマットのサポート
  • レスポンスのストリーミング機能
  • パフォーマンスおよび機能の強化

基本的なリクエスト

クエリ API エンドポイント用の SQL:

SELECT database, name AS num_tables FROM system.tables LIMIT 3;

バージョン 1

curl -X POST 'https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run' \
--user '<openApiKeyId:openApiKeySecret>' \
-H 'Content-Type: application/json' \
-d '{ "format": "JSONEachRow" }'

バージョン 2

curl 'https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=JSONEachRow' \
--user '<openApiKeyId:openApiKeySecret>' \
-H 'x-clickhouse-endpoint-version: 2'
{"database":"INFORMATION_SCHEMA","num_tables":"COLUMNS"}
{"database":"INFORMATION_SCHEMA","num_tables":"KEY_COLUMN_USAGE"}
{"database":"INFORMATION_SCHEMA","num_tables":"REFERENTIAL_CONSTRAINTS"}

JSONCompactEachRow フォーマットを使用し、クエリ変数とバージョン 2 を指定したリクエスト

クエリ API エンドポイントの SQL:

SELECT name, database FROM system.tables WHERE match(name, {tableNameRegex: String}) AND database = {database: String};
curl 'https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=JSONCompactEachRow&param_tableNameRegex=query.*&param_database=system' \
--user '<openApiKeyId:openApiKeySecret>' \
-H 'x-clickhouse-endpoint-version: 2'
["query_cache", "system"]
["query_log", "system"]
["query_views_log", "system"]

クエリ変数に配列を含む、テーブルにデータを挿入するリクエスト

テーブル定義の SQL:

CREATE TABLE default.t_arr
(
    `arr` Array(Array(Array(UInt32)))
)
ENGINE = MergeTree
ORDER BY tuple()

Query API エンドポイントの SQL:

INSERT INTO default.t_arr VALUES ({arr: Array(Array(Array(UInt32)))});
curl -X POST 'https://console-api.clickhouse.cloud/.api/query-endpoints/&lt;endpoint id&gt;/run' \
--user '&lt;openApiKeyId:openApiKeySecret&gt;' \
-H 'Content-Type: application/json' \
-H 'x-clickhouse-endpoint-version: 2' \
-d '{
  "queryVariables": {
    "arr": [[[12, 13, 0, 1], [12]]]
  }
}'

ClickHouse の設定 max_threads を 8 にしたリクエスト

クエリ API エンドポイントの SQL:

SELECT * FROM system.tables;
curl 'https://console-api.clickhouse.cloud/.api/query-endpoints/&lt;endpoint id&gt;/run?max_threads=8' \
--user '&lt;openApiKeyId:openApiKeySecret&gt;' \
-H 'x-clickhouse-endpoint-version: 2'

レスポンスをストリームとしてリクエストしてパースする`

クエリ API エンドポイントの SQL:

SELECT name, database FROM system.tables;
async function fetchAndLogChunks(
  url: string,
  openApiKeyId: string,
  openApiKeySecret: string
) {
  const auth = Buffer.from(`${openApiKeyId}:${openApiKeySecret}`).toString(
    "base64"
  );

  const headers = {
    Authorization: `Basic ${auth}`,
    "x-clickhouse-endpoint-version": "2",
  };

  const response = await fetch(url, {
    headers,
    method: "POST",
    body: JSON.stringify({ format: "JSONEachRow" }),
  });

  if (!response.ok) {
    console.error(`HTTP error! Status: ${response.status}`);
    return;
  }

  const reader = response.body as unknown as Readable;
  reader.on("data", (chunk) => {
    console.log(chunk.toString());
  });

  reader.on("end", () => {
    console.log("Stream ended.");
  });

  reader.on("error", (err) => {
    console.error("Stream error:", err);
  });
}

const endpointUrl =
  "https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=JSONEachRow";
const openApiKeyId = "<myOpenApiKeyId>";
const openApiKeySecret = "<myOpenApiKeySecret>";
// 使用例
fetchAndLogChunks(endpointUrl, openApiKeyId, openApiKeySecret).catch((err) =>
  console.error(err)
);
> npx tsx index.ts
> {"name":"COLUMNS","database":"INFORMATION_SCHEMA"}
> {"name":"KEY_COLUMN_USAGE","database":"INFORMATION_SCHEMA"}
...
> Stream ended.

ファイルからテーブルにストリーム挿入する

次の内容でファイル ./samples/my_first_table_2024-07-11.csv を作成します:

"user_id","json","name"
"1","{""name"":""John"",""age"":30}","John"
"2","{""name"":""Jane"",""age"":25}","Jane"

CREATE TABLE 文:

create table default.my_first_table
(
    user_id String,
    json String,
    name String,
) ENGINE = MergeTree()
ORDER BY user_id;

クエリ API エンドポイント用 SQL:

INSERT INTO default.my_first_table
cat ./samples/my_first_table_2024-07-11.csv | curl --user '<openApiKeyId:openApiKeySecret>' \
                                                   -X POST \
                                                   -H 'Content-Type: application/octet-stream' \
                                                   -H 'x-clickhouse-endpoint-version: 2' \
                                                   "https://console-api.clickhouse.cloud/.api/query-endpoints/<endpoint id>/run?format=CSV" \
                                                   --data-binary @-