Astro DBを試す
Astro DBがリリースされたので試してみる。
まずはAstro Studioでアカウント作成。
次にプロジェクト作成、作成方法が聞かれるので
ひとまず「Create from Template」を選んでみる。
次にどのテンプレートにするかが聞かれる
テンプレートは「Blank Project」を選んでみる。
GitHubのレポジトリの権限を要求される。
ので権限を与えました、このタイミングではリポジトリの作成は不要なので適当なリポジトリへのアクセス権限を割りあてて「swing-astro-db」というリポジトリをAstro Studioから作成しました。
これでプロジェクト作成は終了
作成したリポジトリをクローンして設定をする。
git clone git@github.com:KazumaNishihata/swing-astro-db.git
cd swing-astro-db
npm install
npm run dev
DB作成
DBの設定はdb/config.ts
に記述。
まずはシンプルに著者情報(author)と本文(body)をもつCommentテーブルを作成
import { defineDb, defineTable, column } from 'astro:db';
const Comment = defineTable({
columns: {
id: column.number({ primaryKey: true }),
author: column.text(),
body: column.text(),
}
})
export default defineDb({
tables: { Comment },
})
db/seed.ts
にはデフォルトデータを入れておく。
(最初試したときは型情報が.astro/db-types.d.ts
に反映されるまで時間がかかったので必要に応じてアプリの再起動など必要かも)
import { db, Comment } from 'astro:db';
export default async function() {
await db.insert(Comment).values([
{ id:1, author: 'author1', body: 'comment1' },
{ id:2, author: 'author2', body: 'comment2' },
])
}
テーブルの取得
src/pages/index.astro
でこの情報を読み込んでみる。
DBアクセスはDrizzle ORMを利用する
以下のようにしてコメントの取得と表示ができる
---
import { db, Comment } from 'astro:db';
const comments = await db.select().from(Comment);
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
<h2>Comments</h2>
<ul>
{
comments.map(({ author, body }) => (
<li>
<strong>{author}</strong>
{body}
</li>
))
}
</ul>
</body>
</html>
情報の追加
POST情報を扱うにはレンダリングをSSRに変更する必要がある。
astro.config.mjs
にoutput: "server",
を追記
import db from '@astrojs/db';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({
integrations: [db()],
+ output: "server",
});
src/pages/index.astro
に以下を追加すると入力フォームが追加されてコメントを追記していくことができます。
---
import { db, Comment } from 'astro:db';
if (Astro.request.method === 'POST') {
const formData = await Astro.request.formData();
const author = formData.get('author');
const body = formData.get('body');
if (typeof author === 'string' && typeof body === 'string') {
await db.insert(Comment).values({ author, body });
}
}
const comments = await db.select().from(Comment);
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
<h2>Comments</h2>
<ul>
{
comments.map(({ author, body }) => (
<li>
<strong>{author}</strong>
{body}
</li>
))
}
</ul>
<form method="POST">
<label for="author">Author</label>
<input id="author" name="author" />
<label for="body">body</label>
<input id="body" name="body" />
<button>Submit</button>
</form>
</body>
</html>
この状態で一度GitHubにpush。そうするとAstro stuido上にもテーブルが作成さている。
連携が簡単だ
一度CloudeFlareにリリースして動作するか確認してみる。
以下のコマンドでCloudeflare用のadapterを追加
npx astro add cloudflare
astro.config.mjs
の設定を変更してGit Push
import db from '@astrojs/db';
import { defineConfig } from 'astro/config';
+import cloudflare from "@astrojs/cloudflare";
// https://astro.build/config
export default defineConfig({
integrations: [db()],
output: "server",
+ adapter: cloudflare(),
});
Cloudeflareでは新たにプロジェクトを作成しておきます。
これでデプロイしてもうまく動かず
以下でAstro Studioとの連携が手詰まり。
astro db login
でログインは成功するが astro db link
で連携しようとすると認証エラーでログインしろと言われる。
% astro db login
Opening the following URL in your browser...
https://stardate.astro.build/auth/cli/login?returnTo=http%3A%2F%2Flocalhost%3A60021
If something goes wrong, copy-and-paste the URL into your browser.
✔ Successfully logged in!
% astro db link
? Link "~/Desktop/astro/swing-astro-db" with Astro Studio? › (Y/n)Unauthorized
Are you logged in?
Run astro db login to authenticate and then try linking again.
astro db link
で連携できないエラーは @astrojs/db
のバージョンを0.7.2
->0.8.2
にアップデートしたら解決
% npx astro add db
✔ Resolving packages...
Astro will run the following command:
If you skip this step, you can always run it yourself later
╭─────────────────────────────────╮
│ npm install @astrojs/db@^0.8.2 │
╰─────────────────────────────────╯
✔ Continue? … yes
✔ Installing dependencies...
success Configuration up-to-date.
ローカルでビルドを試すがエラーに
package.json
のbuildコマンドに--remote
オプションを付けて
"scripts": {
"dev": "astro dev",
"start": "astro dev",
+ "build": "astro build --remote",
"preview": "astro preview",
"astro": "astro"
},
ビルドを実行
% npm run build
> studio-template-empty@0.0.1 build
> astro build --remote
21:25:47 [WARN] [@astrojs/cloudflare] The current configuration does not support image optimization. To allow your project to build with the original, unoptimized images, the image service has been automatically switched to the 'noop' option. See https://docs.astro.build/en/reference/configuration-reference/#imageservice
21:25:47 [vite] Re-optimizing dependencies because vite config has changed
21:25:47 [astro:db] database: remote
21:25:47 [build] output: "server"
21:25:47 [build] directory: /swing-astro-db/dist/
21:25:47 [build] adapter: @astrojs/cloudflare
21:25:47 [build] Collecting build info...
21:25:47 [build] ✓ Completed in 2.84s.
21:25:47 [build] Building server entrypoints...
21:25:48 [vite] ✓ built in 588ms
21:25:48 [build] ✓ Completed in 619ms.
21:25:48
finalizing server assets
21:25:48 [build] Rearranging server assets...
✘ [ERROR] Could not resolve "node:fs"
node_modules/vite/dist/node/index.js:6:41:
6 │ import { existsSync, readFileSync } from 'node:fs';
╵ ~~~~~~~~~
The package "node:fs" wasn't found on the file system but is built into node. Are you trying to
bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
✘ [ERROR] Could not resolve "node:fs/promises"
node_modules/vite/dist/node/index.js:8:7:
8 │ import 'node:fs/promises';
╵ ~~~~~~~~~~~~~~~~~~
以下の修正がリリースされたら多分なおるヤツ(後で気づいたけど3/14の日付だったのでこの日マージされたかとおもったけど1年前の3/14だったので関係なかった)
1晩寝かしたら@astrojs/db
とastro
の新しいバージョンがリリースされてたのでアップデート
% npm outdated
Package Current Wanted Latest Location Depended by
@astrojs/db 0.8.2 0.8.5 0.8.5 node_modules/@astrojs/db swing-astro-db
astro 4.5.3 4.5.4 4.5.4 node_modules/astro swing-astro-db
wrangler 3.34.0 3.34.2 3.34.2 node_modules/wrangler swing-astro-db
そうするとビルド通りました。
% npm run build
> studio-template-empty@0.0.1 build
> astro build --remote
✔ Connected to remote database.
プロダクト的に不安定そうなのでハマったら1晩寝かすのがよさそう
ビルドできてたのでwranglerを利用してローカルで確認
% npx wrangler pages dev ./dist --compatibility-date=2024-03-15
✨ Compiled Worker successfully
⛅️ wrangler 3.34.2
-------------------
[wrangler:inf] Ready on http://localhost:8788
起動はできたけど http://localhost:8788
にアクセスするとエラーになる。
認証がうまく行ってない、nodeアダプターで試しても同様になるのでなにか設定が足りてないのだと思う
✘ [ERROR] 10:27:20 [ERROR] Error: Failed to execute query.
Query: select "id", "author", "body" from "Comment"
Full error: 401 Unauthorized
at null.<anonymous>
(file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/dist/_worker.js:62:76024)
at aa (file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/dist/_worker.js:62:75774)
at async n.map.sql
(file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/dist/_worker.js:62:75892)
at async Xo.all
(file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/dist/_worker.js:62:21173)
at null.<anonymous> (async
file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/.wrangler/tmp/dev-QA61zE/gtrnlvneoy4.js:6699:13)
at async pi
(file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/dist/_worker.js:25:278)
at async lp
(file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/dist/_worker.js:24:113)
at async Sc
(file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/dist/_worker.js:41:2599)
at async Response.status
(file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/dist/_worker.js:83:11884)
at async Wg
(file:///Users/nishihatakazuma/Desktop/astro/swing-astro-db/dist/_worker.js:83:3268)
[wrangler:inf] GET / 500 Internal Server Error (320ms)
トークンの指定が必要だった.env
に作成したトークンをいれる
ASTRO_STUDIO_APP_TOKEN=xxxxxx
これで動作。Cloudeflareでも動作確認
記事に清書中