Перейти к основному содержанию
Перейти к основному содержанию

Настройка конечных точек API для запросов

Функция Query API Endpoints позволяет создавать конечные точки API напрямую из любого сохранённого SQL‑запроса в консоли ClickHouse Cloud. Вы сможете обращаться к конечным точкам API по HTTP, чтобы выполнять сохранённые запросы, не подключаясь к вашему сервису ClickHouse Cloud с использованием нативного драйвера.

Предварительные требования

Прежде чем продолжить, убедитесь, что у вас есть:

  • Ключ API с соответствующими правами доступа
  • Роль Admin Console

Вы можете воспользоваться этим руководством, чтобы создать ключ API, если у вас его еще нет.

Минимальные права доступа

Чтобы выполнять запросы к API endpoint, ключ API должен иметь роль организации Member с доступом к сервису Query Endpoints. Роль базы данных настраивается при создании endpoint.

Создание сохраненного запроса

Если у вас уже есть сохраненный запрос, вы можете пропустить этот шаг.

Откройте новую вкладку запроса. В демонстрационных целях мы будем использовать набор данных youtube, который содержит примерно 4,5 миллиарда записей. Следуйте шагам из раздела "Создание таблицы", чтобы создать таблицу в вашем облачном сервисе и вставить в нее данные.

Совет
Ограничьте количество строк с помощью LIMIT

В учебном примере с набором данных вставляется большой объем данных — 4,65 миллиарда строк, что может занять некоторое время. Для целей данного руководства мы рекомендуем использовать оператор LIMIT, чтобы вставить меньший объем данных, например 10 миллионов строк.

В качестве примерного запроса мы вернем 10 лучших авторов по среднему количеству просмотров на видео за указанный пользователем параметр year.

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
-- highlight-next-line
  toYear(upload_date) = {year: UInt16}
GROUP BY uploader
ORDER BY per_upload desc
  LIMIT 10

Обратите внимание, что этот запрос содержит параметр (year), который выделен в приведенном выше фрагменте. Вы можете указывать параметры запроса, используя фигурные скобки { } вместе с указанием типа параметра. Редактор запросов SQL console автоматически обнаруживает выражения параметров запроса ClickHouse и предоставляет поле ввода для каждого параметра.

Быстро запустим этот запрос, чтобы убедиться, что он работает, указав год 2010 в поле ввода переменных запроса в правой части редактора SQL:

Тестовый запуск примерного запроса

Затем сохраните запрос:

Сохранение примерного запроса

Дополнительную документацию по сохраненным запросам можно найти в разделе "Сохранение запроса".

Настройка Query API endpoint

Query API endpoints можно настраивать непосредственно из представления запроса, нажав кнопку Share и выбрав API Endpoint. Вам будет предложено указать, какие ключи API должны иметь доступ к этому endpoint:

Настройка endpoint запроса

После выбора ключа API вам будет предложено:

  • Выбрать роль базы данных, которая будет использоваться для выполнения запроса (Full access, Read only или Create a custom role)
  • Указать разрешенные домены для совместного использования ресурсов между источниками (CORS)

После выбора этих параметров Query API endpoint будет автоматически создан.

Будет показана примерная команда curl, с помощью которой вы можете отправить тестовый запрос:

Команда curl для endpoint

Команда 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 endpoint вы можете протестировать его работу, используя curl или любой другой HTTP‑клиент:

Тестирование endpoint с помощью curl

После того как вы отправите первый запрос, сразу справа от кнопки Share должна появиться новая кнопка. При нажатии она откроет выезжающую панель, содержащую данные мониторинга по этому запросу:

Мониторинг endpoint

Подробности реализации

Этот endpoint выполняет запросы к вашим сохранённым endpoint'ам Query API. Он поддерживает несколько версий, гибкие форматы ответа, параметризованные запросы и опциональные потоковые ответы (только для версии 2).

Endpoint:

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

HTTP-методы

MethodUse CaseParameters
GETПростые запросы с параметрамиПередавайте переменные запроса через параметры URL (?param_name=value)
POSTСложные запросы или при использовании тела запросаПередавайте переменные запроса в теле запроса (объект queryVariables)

Когда использовать GET:

  • Простые запросы без сложных вложенных данных
  • Параметры можно легко закодировать в URL
  • Преимущества кэширования благодаря семантике HTTP GET

Когда использовать POST:

  • Сложные переменные запроса (массивы, объекты, длинные строки)
  • Когда для целей безопасности/конфиденциальности предпочтительно тело запроса
  • Потоковая загрузка файлов или больших объёмов данных

Аутентификация

Обязательно: Да
Метод: Базовая аутентификация (Basic Auth) с использованием OpenAPI Key/Secret
Права доступа: Необходимые права для конечной точки запроса

Конфигурация запроса

Параметры URL

ПараметрОбязательноОписание
queryEndpointIdДаУникальный идентификатор конечной точки запроса для выполнения

Параметры запроса

ПараметрОбязательноОписаниеПример
formatНетФормат ответа (поддерживаются все форматы ClickHouse)?format=JSONEachRow
param_:nameНетПеременные запроса, когда тело запроса передаётся потоком. Замените :name на имя вашей переменной?param_year=2024
:clickhouse_settingНетЛюбая поддерживаемая настройка ClickHouse?max_threads=8

Заголовки

HeaderRequiredDescriptionValues
x-clickhouse-endpoint-versionNoУказывает версию конечной точки1 или 2 (по умолчанию используется последняя сохранённая версия)
x-clickhouse-endpoint-upgradeNoИнициирует обновление версии конечной точки (используйте с заголовком версии)1 для обновления

Тело запроса

Параметры

ПараметрТипОбязательноОписание
queryVariablesobjectНетПеременные, которые будут использованы в запросе
formatstringНетФормат ответа

Поддерживаемые форматы

ВерсияПоддерживаемые форматы
Version 2Все форматы, поддерживаемые ClickHouse
Version 1 (limited)TabSeparated
TabSeparatedWithNames
TabSeparatedWithNamesAndTypes
JSON
JSONEachRow
CSV
CSVWithNames
CSVWithNamesAndTypes

Ответы

Успешный ответ

Статус: 200 OK
Запрос был успешно выполнен.

Коды ошибок

Код статусаОписание
400 Bad RequestНекорректный запрос
401 UnauthorizedОтсутствует аутентификация или недостаточно прав
404 Not FoundУказанная конечная точка запроса не найдена

Рекомендации по обработке ошибок

  • Убедитесь, что в запрос включены корректные аутентификационные данные
  • Проверьте queryEndpointId и queryVariables перед отправкой
  • Реализуйте корректную обработку ошибок с информативными сообщениями

Обновление версий конечных точек

Чтобы обновить версию с 1 до 2:

  1. Добавьте заголовок x-clickhouse-endpoint-upgrade со значением 1
  2. Добавьте заголовок x-clickhouse-endpoint-version со значением 2

Это даёт доступ к возможностям версии 2, таким как:

  • Поддержка всех форматов ClickHouse
  • Возможность потоковой передачи ответа
  • Повышенная производительность и функциональность

Примеры

Базовый запрос

SQL конечной точки Query API:

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"}

Запрос с параметрами и версией 2 в формате JSONCompactEachRow

SQL конечной точки Query API:

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()

SQL конечной точки Query API:

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

Запрос с настройкой ClickHouse max_threads, установленной на 8

SQL конечной точки Query API:

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

Запрос и обработка ответа в виде потока

SQL конечной точки Query API:

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! Статус: ${response.status}`)
    return
  }

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

  reader.on("end", () => {
    console.log("Поток завершён.")
  })

  reader.on("error", (err) => {
    console.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"}
...
> Поток завершён.

Вставка потока из файла в таблицу

Создайте файл ./samples/my_first_table_2024-07-11.csv со следующим содержимым:

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

SQL создания таблицы:

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

SQL конечной точки Query API:

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 @-