一个完整的前端交互到数据库写入链路复盘

69 阅读2分钟

在构建一个 AI 模拟测试平台时,遇到了前后端交互的问题。
比如:按钮点了之后,问题怎么生成?数据怎么存进数据库?页面怎么更新? 决定自己彻底拆解,梳理从 0 开始构建系统。


✅ 二、完整流程概览:用户 → AI → 数据库 → 页面


[用户点击按钮][前端 Agent.tsx 触发 handleCall() 函数][fetch 请求 → 后端 route.ts 接收并生成问题][生成问题后 → 存入 Firestore 数据库][后端返回问题 → 前端 setMessages 更新状态][页面重新渲染出 AI 面试问题]

✅ 三、文件结构中两大主角

文件作用
Agent.tsx负责前端 UI、显示面试官和按钮、调用后端接口
route.ts负责接收请求、生成 AI 面试题、存入数据库

✅ 四、每一步的核心逻辑 & 代码拆解


🔹 Step 1. 用户点击按钮,触发 handleCall


<button className="btn-call" onClick={handleCall}>

创建点击事件,发起 POST 请求:


const handleCall = async () => {
  const requestBody = {
    type: 'technical',
    role: 'Frontend Developer',
    level: 'Junior',
    techstack: 'React,TypeScript,Tailwind',
    amount: 5,
    userid: 'user-123',
  };

  const res = await fetch('/api/vapi/generate', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(requestBody),
  });

  const data = await res.json();
  setMessages(data.questions);
};

🔹 Step 2. route.ts 接收请求体,调用 AI 模型生成问题


const { type, role, level, techstack, amount, userid } = await request.json();

const { text: questions } = await generateText({
  model: google("gemini-2.0-flash-001"),
  prompt: `Prepare ${amount} questions for a ${level} ${role} interview with ${techstack}`,
});

🔹 Step 3. 生成问题后,封装对象写入 Firestore


const interview = {
  role,
  type,
  level,
  techstack: techstack.split(','),
  questions: JSON.parse(questions),
  userId: userid,
  createdAt: new Date().toISOString(),
};

await db.collection("interviews").add(interview);

需要提前在 lib/db.ts 中初始化 Firestore,并在此处引入 db


🔹 Step 4. 后端返回成功 → 前端状态更新


return Response.json({ success: true, questions: JSON.parse(questions) });

前端接收到后,调用 setMessages(),页面自动显示问题。


✅ 五、关键技术点总结

技术应用点
✅ React 状态管理控制对话内容显示
✅ fetch API发起 POST 请求
✅ Next.js API Route创建 route.ts 接口文件
✅ Firestore数据库存储、写入对象
✅ AI 文本生成 API使用 Gemini 生成问题内容

✅ 六、从中学到了什么?

  1. 再也不怕“按钮点了没反应”这种模糊的错误了
  2. 数据的流动路径清晰之后,前端页面更可控了

📎 附:项目结构图(推荐截图)


├── app/
│   ├── api/vapi/generate/route.ts ← 后端接口
│   └── components/Agent.tsx ← 前端页面组件
├── lib/db.ts ← 数据库连接
├── public/ai-avatar.png ← 考官头像