← Hyperdrive (Postgres & MySQL) / hyperdrive / tutorials
Создайте бессерверный, глобально распределённый API временных рядов с Timescale
В этом руководстве вы научитесь создавать на Workers API, который будет принимать и запрашивать временные ряды данных, хранящиеся в Timescale ↗ (они делают PostgreSQL быстрее в облаке).
Вы создадите и развернете функцию Worker, которая предоставляет API маршруты для приёма данных, и будете использовать Hyperdrive ↗ чтобы проксировать подключение к вашей базе данных на границе сети и поддерживать пул соединений, чтобы не создавать новое подключение к базе данных при каждом запросе.
Вы узнаете, как:
- Создайте и разверните Cloudflare Worker.
- Используйте секреты Worker вместе с Wrangler CLI.
- Разверните сервис базы данных Timescale.
- Подключите свой Worker к сервису базы данных Timescale с помощью Hyperdrive.
- Отправьте запрос к вашему новому API.
Подробнее о Timescale можно узнать в их документация ↗.
1. Создайте проект Worker
Выполните следующую команду, чтобы создать проект Worker из командной строки:
npm create cloudflare@latest -- timescale-apiДля настройки выберите следующие параметры:
- Для С чего вы хотите начать?, выберите
Hello World example. - Для Какой шаблон вы хотите использовать?, выберите
Worker only. - Для Какой язык вы хотите использовать?, выберите
TypeScript. - Для Хотите использовать git для контроля версий?, выберите
Yes. - Для Хотите развернуть приложение?, выберите
No(мы внесём некоторые изменения перед развёртыванием).
Запишите URL, по которому было развёрнуто ваше приложение. Он понадобится вам при настройке вебхука GitHub.
Перейдите в каталог, который вы только что создали для своего проекта Worker:
cd timescale-api2. Подготовка Timescale Service
Если вы создаете новый сервис, перейдите в Timescale Console ↗ и выполните следующие действия:
- Выберите Create Service выбрав чёрный значок плюс в правом верхнем углу.
- Выберите Временные ряды в качестве типа службы.
- Выберите нужный регион и размер инстанса. Для этого руководства будет достаточно 1 CPU.
- Задайте имя сервиса, чтобы заменить автоматически сгенерированное.
- Выберите Create Service.
- Справа разверните Информация о подключении диалоговом окне и скопируйте URL службы.
- Скопируйте отображаемый пароль. Повторно получить его будет уже нельзя.
- Выберите Я сохранил пароль, перейти к обзору сервиса.
Если вы используете ранее созданный сервис, сведения о подключении к нему можно найти в Timescale Console ↗:
- Выберите сервис (базу данных), к которому должен подключаться Hyperdrive.
- Развернуть Информация о подключении.
- Скопируйте URL службы. Service URL представляет собой строку подключения, которую использует Hyperdrive для соединения. Она включает имя хоста базы данных, номер порта и имя базы данных.
Вставьте свой пароль в URL службы следующим образом (не изменяя часть после @):
postgres://tsdbadmin:YOURPASSWORD@...Далее это будет называться SERVICEURL в следующих разделах.
3. Создание Hypertable
Timescale позволяет преобразовывать обычные таблицы PostgreSQL в гипертаблицы ↗, таблицы, используемые для работы с временными рядами, событиями или аналитическими данными. После этого изменения Timescale будет автоматически управлять партиционированием hypertable, а также позволит применять другие функции, такие как сжатие или непрерывные агрегаты.
Подключитесь к своей базе данных Timescale, используя Service URL, скопированный на предыдущем шаге (он уже содержит пароль).
Если вы используете стандартный инструмент командной строки PostgreSQL psql ↗ для подключения вы бы запустили psql, как показано ниже (подставив свои URL службы из предыдущего шага). Можно также подключиться с помощью графического инструмента, например PgAdmin ↗.
psql <SERVICEURL>После подключения создайте таблицу, вставив следующий SQL-код:
CREATE TABLE readings(
ts timestamptz DEFAULT now() NOT NULL,
sensor UUID NOT NULL,
metadata jsonb,
value numeric NOT NULL
);
SELECT create_hypertable('readings', 'ts');Всё остальное Timescale берёт на себя, пока вы загружаете и запрашиваете данные.
4. Создание конфигурации базы данных
Для создания нового экземпляра Hyperdrive потребуется:
- Ваш SERVICEURL от шаг 2.
- Имя для вашего сервиса Hyperdrive. В этом руководстве вы будете использовать hyperdrive.
Hyperdrive использует create команду с --connection-string аргумент, чтобы передать эту информацию. Выполните команду следующим образом:
npx wrangler hyperdrive create hyperdrive --connection-string="SERVICEURL"Эта команда выводит ID вашего Hyperdrive. Теперь вы можете привязать конфигурацию Hyperdrive к своему Worker в конфигурации Wrangler, заменив содержимое следующим:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "timescale-api",
"main": "src/index.ts",
// Set this to today's date
"compatibility_date": "2026-08-28",
"compatibility_flags": [
"nodejs_compat"
],
"hyperdrive": [
{
"binding": "HYPERDRIVE",
"id": "your-id-here"
}
]
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "timescale-api"
main = "src/index.ts"
# Set this to today's date
compatibility_date = "2026-08-28"
compatibility_flags = [ "nodejs_compat" ]
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "your-id-here"Установите драйвер Postgres в проект Worker:
npm i pgТеперь скопируйте приведенный ниже код Worker и замените им текущий код в ./src/index.ts. Приведенный ниже код:
- Использует Hyperdrive для подключения к Timescale со строкой подключения, полученной из
env.HYPERDRIVE.connectionStringнапрямую драйверу. - Создает
POSTмаршрут, который принимает массив показаний JSON для вставки в Timescale в рамках одной транзакции. - Создает
GETмаршрут, который принимаетlimitпараметр и возвращает самые последние показания. Это можно адаптировать для фильтрации по идентификатору или по временной метке.
import { Client } from "pg";
export interface Env {
HYPERDRIVE: Hyperdrive;
}
export default {
async fetch(request, env, ctx): Promise<Response> {
// Create a new client on each request. Hyperdrive maintains the underlying
// database connection pool, so creating a new client is fast.
const client = new Client({
connectionString: env.HYPERDRIVE.connectionString,
});
await client.connect();
const url = new URL(request.url);
// Create a route for inserting JSON as readings
if (request.method === "POST" && url.pathname === "/readings") {
// Parse the request's JSON payload
const productData = await request.json();
// Write the raw query. You are using jsonb_to_recordset to expand the JSON
// to PG INSERT format to insert all items at once, and using coalesce to
// insert with the current timestamp if no ts field exists
const insertQuery = `
INSERT INTO readings (ts, sensor, metadata, value)
SELECT coalesce(ts, now()), sensor, metadata, value FROM jsonb_to_recordset($1::jsonb)
AS t(ts timestamptz, sensor UUID, metadata jsonb, value numeric)
`;
const insertResult = await client.query(insertQuery, [
JSON.stringify(productData),
]);
// Collect the raw row count inserted to return
const resp = new Response(JSON.stringify(insertResult.rowCount), {
headers: { "Content-Type": "application/json" },
});
return resp;
// Create a route for querying within a time-frame
} else if (request.method === "GET" && url.pathname === "/readings") {
const limit = url.searchParams.get("limit");
// Query the readings table using the limit param passed
const result = await client.query(
"SELECT * FROM readings ORDER BY ts DESC LIMIT $1",
[limit],
);
// Return the result as JSON
const resp = new Response(JSON.stringify(result.rows), {
headers: { "Content-Type": "application/json" },
});
return resp;
}
},
} satisfies ExportedHandler<Env>;5. Разверните Worker
Выполните следующую команду, чтобы повторно развернуть Worker:
npx wrangler deployВаше приложение теперь доступно по адресу timescale-api.<YOUR_SUBDOMAIN>.workers.dev. Точный URI будет показан в выводе только что выполненной команды wrangler.
После развёртывания вы сможете работать с базой данных показаний IoT в Timescale через свой Cloudflare Worker. Подключение с периферии будет быстрее, так как вы используете Cloudflare Hyperdrive.
Теперь Cloudflare Worker можно использовать для добавления новых строк в readings таблица. Чтобы проверить эту функциональность, отправьте POST запрос на URL вашего Worker с /readings путь, а также данные в формате JSON, содержащие данные нового продукта:
[
{ "sensor": "6f3e43a4-d1c1-4cb6-b928-0ac0efaf84a5", "value": 0.3 },
{ "sensor": "d538f9fa-f6de-46e5-9fa2-d7ee9a0f0a68", "value": 10.8 },
{ "sensor": "5cb674a0-460d-4c80-8113-28927f658f5f", "value": 18.8 },
{ "sensor": "03307bae-d5b8-42ad-8f17-1c810e0fbe63", "value": 20.0 },
{ "sensor": "64494acc-4aa5-413c-bd09-2e5b3ece8ad7", "value": 13.1 },
{ "sensor": "0a361f03-d7ec-4e61-822f-2857b52b74b3", "value": 1.1 },
{ "sensor": "50f91cdc-fd19-40d2-b2b0-c90db3394981", "value": 10.3 }
]В этом руководстве не рассматривается ts (временную метку) и metadata (JSON-объект), поэтому они будут установлены в now() и NULL соответственно.
После отправки POST запрос вы также можете отправить GET запрос на URL вашего Worker с /readings путь. Задайте limit параметр для управления количеством возвращаемых записей.
Если у вас есть curl установлен, вы можете протестировать его с помощью следующих команд (замените <YOUR_SUBDOMAIN> вашим поддоменом из команды развертывания выше):
curl --request POST --data @- 'https://timescale-api.<YOUR_SUBDOMAIN>.workers.dev/readings' <<EOF
[
{ "sensor": "6f3e43a4-d1c1-4cb6-b928-0ac0efaf84a5", "value":0.3},
{ "sensor": "d538f9fa-f6de-46e5-9fa2-d7ee9a0f0a68", "value":10.8},
{ "sensor": "5cb674a0-460d-4c80-8113-28927f658f5f", "value":18.8},
{ "sensor": "03307bae-d5b8-42ad-8f17-1c810e0fbe63", "value":20.0},
{ "sensor": "64494acc-4aa5-413c-bd09-2e5b3ece8ad7", "value":13.1},
{ "sensor": "0a361f03-d7ec-4e61-822f-2857b52b74b3", "value":1.1},
{ "sensor": "50f91cdc-fd19-40d2-b2b0-c90db3394981", "metadata": {"color": "blue" }, "value":10.3}
]
EOFcurl "https://timescale-api.<YOUR_SUBDOMAIN>.workers.dev/readings?limit=10"В этом руководстве вы узнали, как создать рабочий пример приема и запроса показаний с периферии на базе Timescale, Workers, Hyperdrive и TypeScript.
Следующие шаги
- Подробнее о Как работает Hyperdrive.
- Подробнее о Timescale ↗.
- См. руководство по устранению неполадок чтобы отладить типичные проблемы.