ℹ️

Astro DB 是 2024 年 3 月发布的 Astro 官方数据库解决方案。

Astro 官方 X 账号。这里会发布包括 Astro DB 在内的最新更新信息。

为什么选择 Astro DB

实现浏览量追踪有多种选择。

方法优点缺点
Vercel Analytics无需配置无法在页面上展示
Upstash Redis速度快依赖外部服务
Astro DB官方支持、类型安全需要与 Astro Studio 联动
Supabase功能丰富配置较为复杂

选择 Astro DB 的理由:

  • 官方支持,更安心
  • 自动生成 TypeScript 类型定义
  • 自动切换:本地开发使用 SQLite,生产环境使用 LibSQL

环境搭建

1. 安装包

npm install @astrojs/db @astrojs/vercel

2. 配置 astro.config.mjs

export default defineConfig({
  output: "hybrid", // API 路由使用 SSR
  adapter: "vercel()",
  integrations: ["db()"],
});
⚠️

output: "hybrid" 是一种允许静态页面与 SSR 页面共存的设置。API 端点将以 SSR 方式运行。


定义数据库 Schema

db/config.ts 中定义表。

const PageViews = defineTable({
  columns: {
    slug: column.text({ primaryKey: true }),
    views: column.number({ default: 0 }),
    updatedAt: column.date({ default: "new Date()" }),
  },
});

export default defineDb({
  tables: { PageViews },
});

实现 API 端点

src/pages/api/views.ts 中进行浏览量的获取与更新。

export const prerender = false; // 以 SSR 模式运行

export const POST: APIRoute = async ({ request }) => {
 const { slug } = await request.json();

 const existing = await db
 .select()
 .from(PageViews)
 .where(eq(PageViews.slug, slug));

 if (existing.length > 0) {
 await db
 .update(PageViews)
 .set({ views: "existing[0"].views + 1 })
 .where(eq(PageViews.slug, slug));
 } else {
 await db.insert(PageViews).values({ slug, views: 1 });
 }

 return new Response(JSON.stringify({ views }));
};

前端组件

ViewCounter.astro 中展示浏览量。

---
interface Props { slug: string; }
const { slug } = Astro.props;
---

<div class="view-counter" data-slug={slug}>
<span class="view-count">--</span> views
</div>

<script>
 const counter = document.querySelector(".view-counter");
 const slug = counter.dataset.slug;

 fetch("/api/views", {
 method: "POST",
 body: JSON.stringify({ slug }),
 })
 .then(res => res.json())
 .then(data => {
 counter.querySelector(".view-count").textContent = data.views;
 });
</script>

部署到生产环境

连接到 Astro Studio 并使用生产数据库。

# 登录
npx astro db login

# 链接项目
npx astro db link

# 推送 Schema
npx astro db push
环境变量配置

请在 Vercel 的环境变量中设置 ASTRO_STUDIO_API_KEY。该 Key 可以从 Astro Studio 的控制面板中获取。


Deep Dive: 使用 Drizzle ORM 实现原子事务

同时进行多项数据更新时,为了保护数据的完整性,需要使用“事务 (Transaction)”。在 Astro DB (Drizzle) 中可以这样写:

await db.transaction(async (tx) => {
  // 要么全部成功,要么全部失败(回滚)
  await tx.insert(PageViews).values({ slug, views: 1 });
  await tx.insert(AuditLogs).values({ action: "view_inc", slug });
});

即使是浏览量计数这种简单的处理,在未来添加日志记录或通知功能时,这种事务处理也将是构建“永不崩溃”系统的关键。


通过使用 Astro DB,我们得以类型安全且简单地实现了浏览量追踪功能。

如果您想深度理解像 Astro 这样先进的 Web 框架或 Jamstack 架构,并希望实现更高级的动态功能,那么这类边动手边学习的实战书籍将非常有帮助。

💡

おすすめ書籍紹介

这是一本可以让你在活用 AI 作为伙伴的同时,学习如何将静态网站生成器、无头 CMS 以及数据库相结合,掌握现代化 Web 开发要领的书。对于 Astro 用户来说,它也是理解周边生态系统的理想选择。

后续步骤:

  • 实现热门文章排行榜
  • 按日/周生成浏览量图表
  • 添加点赞功能