博客搭建教程(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 });
}

第三步:前端评论组件

评论组件分为三部分:

  1. CommentForm — 表单(昵称 + 内容 + 提交按钮)
  2. CommentList — 显示评论列表
  3. 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 });
}

小结

这篇我们:

  1. 理解了 API 的概念
  2. 定义了 Comment 数据模型
  3. 写了 GET 和 POST 接口
  4. 前端评论组件(客户端组件 vs 服务端组件)

下一篇做管理后台和登录功能。


💬 评论

加载中...