技术方案选择:前端、后端、数据库与托管
这一篇让ClearCopy有一个能构建的Astro页面和一个能返回JSON的Fastify接口。你会在本地看到页面文件生成,并用一条命令拿到{"ok":true,"service":"clearcopy-api"}。先把两部分跑起来,再解释PostgreSQL和Railway分别放在哪里,不同时研究十套框架。
本书选定Astro负责页面、Node.js/Fastify负责API、PostgreSQL保存后续账户订单等必要数据、Railway托管。此刻只接前两部分;这不是已经有AI检查能力的网站,也没有真实支付。
把一次操作画成四个位置
用户在Astro页面填原稿,页面把请求发给Fastify;Fastify验证输入、调用模型,必要时读写PostgreSQL,再把结果返回页面。Railway提供运行这些服务的位置。模型密钥和数据库连接只在后端,不能因为前端需要显示结果,就把它们写进浏览器脚本。
本篇配图来自MDN客户端与服务器概览,展示的是静态资源如何返回浏览器。我们先生成一张这样的静态页面,再增加独立API。页面能显示和API能处理请求是两件可以分别验证的事,后续排错也更容易。
先检查Node版本,再安装固定依赖
准备纯文本编辑器、终端和Node.js。运行:
node --version
npm --version
本次实际核对Astro安装说明与npm包信息,Astro 7.4.4要求Node.js至少22.23.4。本机原有22.22.1不符合,因此本书在独立临时环境切换到22.23.4验证,不把“不报找不到node”当作版本已经合格。你可以从Node.js官网安装满足要求的LTS版本,重新打开终端再检查;不要在不清楚其他项目依赖时随意替换共用运行环境。
在自己新建的空目录clearcopy-practice里创建package.json,内容如下。若你已有同名练习文件夹,先另建一个空目录,不覆盖旧文件。
{
"name": "clearcopy-practice",
"private": true,
"type": "module",
"engines": { "node": ">=22.23.4" },
"scripts": {
"dev:web": "astro dev --root web --host 127.0.0.1",
"dev:api": "node api/server.mjs",
"build": "astro build --root web"
},
"dependencies": {
"astro": "7.4.4",
"fastify": "5.12.7"
}
}
这两个版本是本次教学验证固定值。以后更新时重新检查Node前提并跑同一练习,不要把文章中的数字理解成永久推荐版本。安装后保留package-lock.json,让下一次安装能复现同一组依赖。
创建页面并构建
在项目里建立web/src/pages目录,创建index.astro:
---
const title = 'ClearCopy practice';
---
<html lang="en">
<head><meta charset="utf-8" /><title>{title}</title></head>
<body>
<h1>Check your App Store description</h1>
<p>Practice page. No model or payment connected.</p>
</body>
</html>
在项目根目录运行以下命令:
npm install
npm run build
成功时,构建日志应显示静态输出完成,web/dist/index.html出现。打开生成文件,能读到Check your App Store description。本段没有连接外部API,构建成功只说明页面可以生成。
若出现Node版本错误,回到前面的版本检查;若提示没有页面,核对路径是否为web/src/pages/index.astro,不是根目录的src/pages。--root web就是告诉Astro把web作为站点根目录。
需要在浏览器预览时,运行npm run dev:web,按终端显示的本地地址打开,通常使用4321端口。如果该端口被占用,以实际输出为准;结束时在这个终端按Control+C。
让API返回一个不依赖模型的结果
建立api目录,创建server.mjs。这份接口只做健康检查,便于先判断服务能否接收请求。
import Fastify from 'fastify';
const app = Fastify({ logger: true });
app.get('/health', async () => ({
ok: true,
service: 'clearcopy-api'
}));
await app.listen({ port: 4301, host: '127.0.0.1' });
在第一个终端运行npm run dev:api。保持它运行,再在第二个终端执行:
curl http://127.0.0.1:4301/health
预期输出为:
{"ok":true,"service":"clearcopy-api"}
Fastify入门文档使用声明路由、启动监听的同样方式。这里选择本地地址,只让当前电脑访问;部署到Railway时再按平台要求监听端口与地址。若出现EADDRINUSE,4301被其他进程占用;先关闭你自己之前启动的练习服务,不要随意结束不认识的进程。若curl连接失败,检查第一个终端有没有已经退出。
数据库留到需要保存数据时再接
现在目录应该是下面的样子,node_modules无需手工创建:
clearcopy-practice/
package.json
package-lock.json
api/server.mjs
web/src/pages/index.astro
web/dist/index.html
匿名短检查先不保存原稿。等需要订单、额度或用户自己的历史,才接PostgreSQL。PostgreSQL创建数据库教程解释了一个服务器可以管理多个数据库;练习应使用独立数据库,不连真实业务库试写。下一步会明确表里存什么、属于谁,以及哪些原稿根本不必保留。
Railway部署也稍后做,因为本地流程没有跑通时把错误搬上云,只会增加一层需要排查的环境。此刻你已能分别回答“页面能不能构建”“接口能不能返回JSON”。把这两个结果保存下来,再开始实现真正的检查请求,技术方案就从四个名词变成了可以一步步接起来的服务。