2026-10-12 訂正:現行公式資料ではAstro DBはv6.4で非推奨、v7で削除されています。旧稿の新規導入手順を取り下げ、Actionsの入力検証とDB選定を分けました。FormDataにはaccept: 'form'が必要です。astro:schema、output: 'hybrid'、設定評価時の日時defaultの説明も修正しました。
コメント投稿を、入力・権限・保存・表示へ分ける
Astro Actionsを使って投稿入力を整理する設計例です。API routeを自分で書かなくても、serverへ到達する入口は存在します。関数として呼べることと、認証・認可済みであることは別です。静的HTMLだけのhostでDB書き込みActionが動くとは説明しません。
今回確認したのは公式資料と入力schema、codeの構文です。完成したゲストブックを構築・公開した実績ではありません。
1. Astro DBは旧版の機能として読む
公式Astro DBページとv7移行ガイドはintegrationの削除を説明し、DB機能には別libraryへの移行を勧めています。新規projectへastro add dbする現行手順として使いません。
旧版のdb/config.tsやastro:dbを使うprojectでは、採用版、既存schema、接続先、migration、backupを確認してから移行します。型推論があることだけで、DB制約・並行更新・権限・復元が完成するわけではありません。
Astro Studioの終了案内も参照します。旧稿の「Astro Studioへ簡単に本番deploy」は現在の新規導入先として残しません。必要なDB provider、接続credential、費用、実行環境を別途選びます。
2. FormDataを受けるActionの部分例
現行ActionsガイドのZod importはastro/zodです。入力modeを明示します。以下は投稿前の入力確認だけで、DB保存は行いません。
// src/actions/index.ts
import {defineAction, ActionError} from 'astro:actions'
import {z} from 'astro/zod'
export const server = {
prepareComment: defineAction({
accept: 'form',
input: z.object({author: z.string().trim().min(1).max(20), body: z.string().trim().min(1).max(140)}),
handler: async (input, context) => {
if (!context.locals.user) {
throw new ActionError({code: 'UNAUTHORIZED'})
}
return {author: input.author, body: input.body}
},
}),
}
locals.userはアプリ側がsessionを検証して設定する前提です。Astroが自動でログインを作るわけではありません。App.Localsの型、middleware、session失効を実装・検証する必要があります。Cookieの存在だけを本人確認にしません。
空白だけのauthor/bodyもtrim後に拒否します。上限の文字数はJavaScriptの文字列長の規則で、人が見た一文字と必ず同じではありません。HTML等の本文は表示時にescapeし、入力された文字列をそのままHTMLへ挿入しません。
3. フロントは成功と結果不明を分ける
Reactフォーム等からnew FormData(form)を渡す場合、Action側もform modeへそろえます。defaultのJSON入力にFormDataを送る旧稿の組み合わせは修正が必要です。
フォームではlabelのhtmlForとinputのidを結び、必須・上限、pending、error、成功通知を用意します。複数フォームがある場合はIDの衝突を避けます。画面のdisabledは操作上の重複を減らすもので、serverでの二重投稿防止ではありません。
入力確認Actionの戻り値を「投稿しました」と表示しません。書き込みActionを追加した後も、通信失敗は書き込み失敗確定とは限らないため、内容を消さず結果確認の導線を残します。reloadだけで成功メッセージが消える設計も避けます。
4. 保存するActionに必要な条件
保存では、投稿可能な利用者・対象の認可、rate limit、spam・moderation、本文サイズ、処理状態、二重投稿防止を確認します。署名済みsession等の認証情報と、フォームから来た表示名は別です。クライアントの利用者IDをそのまま権限判断に使いません。
受付IDと利用者の組み合わせへDB制約を置く等、同時実行にも対応する規則を設計します。同じIDで内容が違う再送は無条件に成功扱いにしません。DB commit後に応答が失われた場合、同じ受付から既存結果を照合します。ここではそのDB実装は掲載していません。
旧稿のcolumn.date({default: new Date()})は設定評価時の値で、各投稿時の現在時刻を生成する関数ではありません。採用DBの適切なserver-side default、またはinsert時のserver時刻を使い、timezoneとclockの方針を決めます。新しい投稿日時をクライアントに自由に指定させません。
5. 動的配信・取得上限・復旧を確認する
v5移行ガイドではoutput: 'hybrid'が削除されています。採用版に合わせ、対応adapterとoutput: 'server'、または対象routeのprerender = false等を選びます。設定名だけでDB接続・Action・最新一覧の配信が完成するわけではありません。
一覧は全件無制限取得を避け、上限とpagingを設計します。日時だけの並びは同時刻の順序が不定になり得るため、ID等の安定した条件も考えます。投稿成功、一覧再取得、配信cacheを別に確認します。
正常入力、空白、不正型、上限超過、未認証・認可外、rate limit、同時再送、commit結果不明、DB停止、削除、復元を確認します。今回ローカルで確認したのは合成入力のschema判定とTS構文です。Astro型・実行、session、DB、フォーム、adapter、配信・復旧は未検証です。
この記事を書いた人✏️@YushiYamamoto
ITPRODX.com代表 / AIアーキテクト
Next.js / TypeScript / n8nを活用した自律型アーキテクチャ設計を専門としています。
日々の自動化の検証結果や、ビジネス側の視点(ROI等)に関するより深い考察は、以下の公式サイトおよびnoteで発信しています。