INTEGRITY Документация

Создание API для доступа к D1 через прокси-Worker

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

Это полезно, если нужно обращаться к базе данных D1 вне проекта Worker или Pages, настраивать управление доступом и/или ограничивать список таблиц, к которым можно делать запросы.

встроенная в D1 REST API лучше всего подходит для административного использования в качестве глобального Лимит запросов Cloudflare API применяется.

Чтобы обращаться к базе данных D1 вне проекта Worker, нужно создать API с помощью Worker. После этого приложение сможет безопасно взаимодействовать с этим API для выполнения запросов D1.

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

  1. Зарегистрируйтесь для получения Аккаунт Cloudflare.
  2. Установка Node.js.
  3. У вас уже есть база данных D1. См. Руководство по началу работы с D1.

менеджер версий Node.js

Используйте менеджер версий Node, например Volta или nvm чтобы избежать проблем с правами доступа и менять версии Node.js. Wrangler, рассмотренная далее в этом руководстве, требует версии Node 16.17.0 или более поздней версии.

1. Создать новый проект

Создайте новый Worker, чтобы создать и развернуть свой API.

  1. Создайте Worker с именем d1-http выполнив:

    npm create cloudflare@latest -- d1-http

    Для настройки выберите следующие параметры:

    • Для С чего вы хотите начать?, выберите Hello World example.
    • Для Какой шаблон вы хотите использовать?, выберите Worker only.
    • Для Какой язык вы хотите использовать?, выберите TypeScript.
    • Для Хотите использовать git для контроля версий?, выберите Yes.
    • Для Хотите развернуть приложение?, выберите No (мы внесём некоторые изменения перед развёртыванием).
  2. Перейдите в каталог нового проекта, чтобы начать разработку:

    cd d1-http

2. Установите Hono

В этом руководстве вы будете использовать Hono, фреймворк в стиле Express.js, для создания API.

  1. Чтобы использовать Hono в этом проекте, установите его с помощью npm:

    npm i hono

3. Добавьте API_KEY

Для выполнения аутентифицированных вызовов API нужен API-ключ. Чтобы обеспечить его безопасность, добавьте его как secret.

  1. Для локальной разработки создайте .dev.vars файл в корневом каталоге d1-http.

  2. Добавьте свой API-ключ в файл следующим образом.

    .dev.vars
    API_KEY="YOUR_API_KEY"

    Замените YOUR_API_KEY с корректным строковым значением. Это значение также можно сгенерировать с помощью следующей команды.

    openssl rand -base64 32

4. Инициализируйте приложение

Чтобы инициализировать приложение, импортируйте необходимые пакеты, создайте новое приложение Hono и настройте следующее промежуточное ПО:

  1. Замените содержимое src/index.ts файл с помощью приведённого ниже кода.

    src/index.ts
    import { Hono } from "hono";
    import { bearerAuth } from "hono/bearer-auth";
    import { logger } from "hono/logger";
    import { prettyJSON } from "hono/pretty-json";
    
    type Bindings = {
    	API_KEY: string;
    };
    
    const app = new Hono<{ Bindings: Bindings }>();
    
    app.use("*", prettyJSON(), logger(), async (c, next) => {
    	const auth = bearerAuth({ token: c.env.API_KEY });
    	return auth(c, next);
    });

5. Добавьте конечные точки API

  1. Добавьте следующий фрагмент кода в свой src/index.ts.

    src/index.ts
    
    // Paste this code at the end of the src/index.ts file
    
    app.post("/api/all", async (c) => {
    	return c.text("/api/all endpoint");
    });
    
    app.post("/api/exec", async (c) => {
    	return c.text("/api/exec endpoint");
    });
    
    app.post("/api/batch", async (c) => {
    	return c.text("/api/batch endpoint");
    });
    
    export default app;

    Это добавляет следующие конечные точки:

    • POST /api/all
    • POST /api/exec
    • POST /api/batch
  2. Запустите сервер разработки с помощью следующей команды:

    npm run dev
  3. Чтобы протестировать API локально, откройте второй терминал.

  4. Во втором терминале выполните приведённую ниже команду cURL. Замените YOUR_API_KEY со значением, которое вы задали в .dev.vars файл.

    curl -H "Authorization: Bearer YOUR_API_KEY" "http://localhost:8787/api/all" --data '{}'

    Должен появиться следующий вывод:

    /api/all endpoint
  5. Остановите локальный сервер, нажав x в первом терминале.

Приложение Hono готово к работе. Вы можете протестировать остальные конечные точки и при необходимости добавить новые. Пока API не возвращает никаких данных из базы. На следующих шагах вы создадите базу данных, добавите её привязки и обновите конечные точки для взаимодействия с базой данных.

6. Создайте базу данных

Если у вас еще нет базы данных D1, создать новую можно с помощью wrangler d1 create.

  1. В терминале выполните:

    npx wrangler d1 create d1-http-example

    Возможно, потребуется войти в аккаунт Cloudflare. После входа команда создаст новую базу данных D1. В терминале должен появиться примерно такой вывод.

    ✅ Successfully created DB 'd1-http-example' in region EEUR
    Created your new D1 database.
    
    [[d1_databases]]
    binding = "DB" # i.e. available in your Worker on env.DB
    database_name = "d1-http-example"
    database_id = "1234567890"

Запишите отображаемый database_name и database_id. Вы будете использовать это для ссылки на базу данных, создав привязка.

7. Добавьте привязку

  1. Из вашего d1-http папку и откройте файл Wrangler, файл конфигурации Wrangler.

  2. Добавьте следующую привязку в файл. Убедитесь, что database_name и database_id верны.

    {
      "d1_databases": [
        {
          "binding": "DB", // i.e. available in your Worker on env.DB
          "database_name": "d1-http-example",
          "database_id": "1234567890"
        }
      ]
    }
    [[d1_databases]]
    binding = "DB"
    database_name = "d1-http-example"
    database_id = "1234567890"
  3. В вашем src/index.ts файл, обновите Bindings тип, добавив DB: D1Database.

    type Bindings = {
    	DB: D1Database;
    	API_KEY: string;
    };

Теперь у вас есть доступ к базе данных в приложении Hono.

8. Создайте таблицу

Чтобы создать таблицу в только что созданной базе данных:

  1. Создайте новую папку с именем schemas внутри вашего d1-http папка.

  2. Создайте новый файл с именем schema.sql, и вставьте следующий SQL-оператор в файл.

    schema.sql
    DROP TABLE IF EXISTS posts;
    CREATE TABLE IF NOT EXISTS posts (
    	id integer PRIMARY KEY AUTOINCREMENT,
    	author text NOT NULL,
    	title text NOT NULL,
    	body text NOT NULL,
    	post_slug text NOT NULL
    );
    INSERT INTO posts (author, title, body, post_slug) VALUES ('Harshil', 'D1 HTTP API', 'Learn to create an API to query your D1 database.','d1-http-api');

    Этот код удаляет любую таблицу с именем posts если она существует, а затем создаёт новую таблицу posts с полем id, author, title, body, а также post_slug. Затем для заполнения таблицы используется оператор INSERT.

  3. В терминале выполните следующую команду, чтобы создать эту таблицу:

    npx wrangler d1 execute d1-http-example --file=./schemas/schema.sql

После успешного выполнения в вашу базу данных будет добавлена новая таблица.

9. Выполните запрос к базе данных

Теперь приложение может обращаться к базе данных D1. На этом шаге вы обновите конечные точки API для запроса к базе данных и возврата результата.

  1. В вашем src/index.ts файл, обновите код следующим образом.

    src/index.ts
    // Update the API routes
    
    /**
    * Executes the `stmt.run()` method.
    * https://developers.cloudflare.com/d1/worker-api/prepared-statements/#run
    */
    
    app.post('/api/all', async (c) => {
    		return c.text("/api/all endpoint");
    	try {
    		let { query, params } = await c.req.json();
    		let stmt = c.env.DB.prepare(query);
    		if (params) {
    			stmt = stmt.bind(params);
    		}
    
    		const result = await stmt.run();
    		return c.json(result);
    	} catch (err) {
    		return c.json({ error: `Failed to run query: ${err}` }, 500);
    	}
    });
    
    /**
    * Executes the `db.exec()` method.
    * https://developers.cloudflare.com/d1/worker-api/d1-database/#exec
    */
    
    app.post('/api/exec', async (c) => {
    		return c.text("/api/exec endpoint");
    	try {
    		let { query } = await c.req.json();
    		let result = await c.env.DB.exec(query);
    		return c.json(result);
    	} catch (err) {
    		return c.json({ error: `Failed to run query: ${err}` }, 500);
    	}
    });
    
    /**
    * Executes the `db.batch()` method.
    * https://developers.cloudflare.com/d1/worker-api/d1-database/#batch
    */
    
    app.post('/api/batch', async (c) => {
    		return c.text("/api/batch endpoint");
    	try {
    		let { batch } = await c.req.json();
    		let stmts = [];
    		for (let query of batch) {
    			let stmt = c.env.DB.prepare(query.query);
    			if (query.params) {
    				stmts.push(stmt.bind(query.params));
    			} else {
    				stmts.push(stmt);
    			}
    		}
    		const results = await c.env.DB.batch(stmts);
    		return c.json(results);
    	} catch (err) {
    		return c.json({ error: `Failed to run query: ${err}` }, 500);
    	}
    });
    ...

В приведенном выше коде конечные точки обновлены для получения query и params. Эти запросы и параметры передаются в соответствующие функции для взаимодействия с базой данных.

10. Протестируйте API

Теперь, когда API может запрашивать базу данных, вы можете протестировать его локально.

  1. Запустите сервер разработки, выполнив следующую команду:

    npm run dev
  2. В новом окне терминала выполните следующие команды cURL. Обязательно замените YOUR_API_KEY с правильным значением.

    /api/all
    curl -H "Authorization: Bearer YOUR_API_KEY" "http://localhost:8787/api/all" --data '{"query": "SELECT title FROM posts WHERE id=?", "params":1}'
    /api/batch
    curl -H "Authorization: Bearer YOUR_API_KEY" "http://localhost:8787/api/batch" --data '{"batch": [ {"query": "SELECT title FROM posts WHERE id=?", "params":1},{"query": "SELECT id FROM posts"}]}'
    /api/exec
    curl -H "Authorization: Bearer YOUR_API_KEY" "localhost:8787/api/exec" --data '{"query": "INSERT INTO posts (author, title, body, post_slug) VALUES ('\''Harshil'\'', '\''D1 HTTP API'\'', '\''Learn to create an API to query your D1 database.'\'','\''d1-http-api'\'')" }'

Если всё реализовано верно, приведенные выше команды должны выполниться успешно.

11. Разверните API

Теперь, когда всё работает как ожидается, остался последний шаг: развернуть приложение в сети Cloudflare. Для развёртывания API вы используете Wrangler.

  1. Чтобы использовать API в продакшене, а не локально, добавьте таблицу в удалённую (продакшен) базу данных. Для этого выполните следующую команду:

    npx wrangler d1 execute d1-http-example --file=./schemas/schema.sql --remote

    Теперь таблицу можно просмотреть на Cloudflare dashboard > Storage & Databases > D1.

  2. Чтобы развернуть приложение в сети Cloudflare, выполните следующую команду:

    npx wrangler deploy
     ⛅️ wrangler 3.78.4 (update available 3.78.5)
    -------------------------------------------------------
    
    Total Upload: 53.00 KiB / gzip: 13.16 KiB
    Your worker has access to the following bindings:
    - D1 Databases:
      - DB: d1-http-example (DATABASE_ID)
    Uploaded d1-http (4.29 sec)
    Deployed d1-http triggers (5.57 sec)
      [DEPLOYED_APP_LINK]
    Current Version ID: [BINDING_ID]

    После успешного развёртывания в терминале появится ссылка на развёрнутое приложение (DEPLOYED_APP_LINK). Запишите это значение.

  3. Создайте новый API-ключ для использования в продакшене.

    openssl rand -base64 32
    [YOUR_API_KEY]
  4. Выполните wrangler secret put команду, чтобы добавить API в развёрнутый проект.

    npx wrangler secret put API_KEY
    ✔ Enter a secret value:

    Терминал предложит ввести секретное значение.

  5. Введите значение ключа API (YOUR_API_KEY). Теперь ваш API-ключ будет добавлен в проект. С помощью этого значения можно выполнять защищённые вызовы API к развёрнутому вами API.

    ✔ Enter a secret value: [YOUR_API_KEY]
    🌀 Creating the secret for the Worker "d1-http"
    ✨ Success! Uploaded secret API_KEY
  6. Чтобы протестировать это, выполните следующую команду cURL с правильным YOUR_API_KEY и DEPLOYED_APP_LINK.

    • Используйте YOUR_API_KEY который вы сгенерировали в качестве секретного API-ключа.
    • Вы также можете найти свой DEPLOYED_APP_LINK из панели управления Cloudflare > Workers & Pages > d1-http > Настройки > Domains & Routes.
    curl -H "Authorization: Bearer YOUR_API_KEY" "https://DEPLOYED_APP_LINK/api/exec" --data '{"query": "SELECT 1"}'

Сводка

В этом руководстве вы выполнили следующее:

  1. API, взаимодействующий с базой данных D1, создан.
  2. Это API было развёрнуто в Workers. Его можно использовать во внешнем приложении для выполнения запросов к базе данных D1. Полный код этого руководства можно найти на GitHub.

Следующие шаги

Похожую реализацию с использованием Zod для валидации можно найти в этот репозиторий GitHub. Если вы хотите создать API, соответствующий стандарту OpenAPI, для своей базы данных D1, используйте Шаблон Cloudflare Workers OpenAPI 3.1.