博客搭建教程(4):评论系统
API(Application Programming Interface)是一组 URL 地址,前端通过访问这些 URL 来获取数据或提交数据。 比如我们要提交评论,就发一个 POST 请求到 /api/comments。 类比:API 就像是餐厅的服务员。你(前端)告诉服务员你要什么(请求),服务员去厨房(数据库)取菜,然后端给你(响应)。 在 prisma/schema.prisma 里添加...
博客搭建教程(4):评论系统 — 让读者可以留言
什么是 API?
API(Application Programming Interface)是一组 URL 地址,前端通过访问这些 URL 来获取数据或提交数据。
比如我们要提交评论,就发一个 POST 请求到 /api/comments。
类比:API 就像是餐厅的服务员。你(前端)告诉服务员你要什么(请求),服务员去厨房(数据库)取菜,然后端给你(响应)。
第一步:定义 Comment 模型
在 prisma/schema.prisma 里添加:
model Comment {
id String @id @default(cuid())
author String // 评论者昵称
content String // 评论内容
postId String // 属于哪篇文章
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
parentId String? // 回复给谁(可为空)
parent Comment? @relation("Replies", fields: [parentId], references: [id], onDelete: Cascade)
replies Comment[] @relation("Replies")
approved Boolean @default(false) // 需要审核
createdAt DateTime @default(now())
}
parentId 实现回复功能:"我回复张三的评论"就是把我的评论的 parentId 设为张三那条的 ID。
onDelete: Cascade:删文章时自动删评论。
然后运行 npx prisma db push 更新数据库。
第二步:评论 API
创建 src/app/api/comments/route.ts:
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
// GET /api/comments?postId=xxx — 获取某篇文章的评论
export async function GET(request: NextRequest) {
const postId = request.nextUrl.searchParams.get("postId");
if (!postId) return NextResponse.json({ error: "缺少postId" }, { status: 400 });
const comments = await prisma.comment.findMany({
where: { postId, approved: true, parentId: null }, // 只查已审核的顶级评论
include: { replies: { where: { approved: true } } }, // 含审核通过的回复
orderBy: { createdAt: "desc" },
});
return NextResponse.json(comments);
}
// POST /api/comments — 提交评论
export async function POST(request: NextRequest) {
const body = await request.json();
const { postId, author, content, parentId } = body;
// 验证
if (!postId || !author?.trim() || !content?.trim()) {
return NextResponse.json({ error: "请填写完整" }, { status: 400 });
}
// 创建评论(默认未审核)
await prisma.comment.create({
data: {
postId,
author: author.trim(),
content: content.trim(),
parentId: parentId || null,
approved: false,
},
});
return NextResponse.json({ success: true }, { status: 201 });
}
第三步:前端评论组件
评论组件分为三部分:
- CommentForm — 表单(昵称 + 内容 + 提交按钮)
- CommentList — 显示评论列表
- CommentSection — 组合上面两个
关键:评论表单是客户端组件("use client"),因为需要处理用户输入和表单提交。这不是服务端组件能做的事。
第四步:审核管理
管理后台需要审核评论。添加 PUT 和 DELETE 接口:
// PUT /api/comments/[id] — 审核通过
export async function PUT(request: NextRequest, { params }: { params: { id: string } }) {
await prisma.comment.update({
where: { id: params.id },
data: { approved: true },
});
return NextResponse.json({ success: true });
}
小结
这篇我们:
- 理解了 API 的概念
- 定义了 Comment 数据模型
- 写了 GET 和 POST 接口
- 前端评论组件(客户端组件 vs 服务端组件)
下一篇做管理后台和登录功能。