chatGpt之Next.js API Routes + 数据库接入 27天-前端-E先生的博客
Java
MySQL
大数据
Python
前端
黑科技
大语言模型
    首页 >> 互联网 >> 前端

chatGpt之Next.js API Routes + 数据库接入 27天

[导读]:🏗 实战项目:Next.js 全栈博客系统(带数据库)目标:Next.js API Routes 作为后端使用 Prisma ORM 连接 MySQL/MongoDB 数据库实现博客的增、删、查、改(CRUD)功能完整的博客系统前后端代码示例1. 初始化数据库首先,确保你有 MySQL 或 MongoDB 环境。如果你使用 MySQL,可以通过以下步骤初始化:dockerrun...

🏗 实战项目:Next.js 全栈博客系统(带数据库)

目标:

  • Next.js API Routes 作为后端

  • 使用 Prisma ORM 连接 MySQL/MongoDB 数据库

  • 实现博客的增、删、查、改(CRUD)功能

  • 完整的博客系统前后端代码示例


1. 初始化数据库

首先,确保你有 MySQL 或 MongoDB 环境。如果你使用 MySQL,可以通过以下步骤初始化:

docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql:5.7

数据库连接成功后,创建 blog 数据库。


2. 安装 Prisma ORM

在 Next.js 项目中,我们将使用 Prisma 来进行数据库的操作。

npm install prisma @prisma/client
npx prisma init

配置数据库连接(prisma/schema.prisma

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL") // 在 .env 文件中设置数据库连接 URL
}

generator client {
  provider = "prisma-client-js"
}

model Post {
  id      Int      @id @default(autoincrement())
  title   String
  body    String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

.env 配置文件(设置数据库连接)

DATABASE_URL="mysql://root:root@localhost:3306/blog"

执行 Prisma Migrate(同步数据库)

npx prisma migrate dev --name init
npx prisma generate

3. 创建 API Routes

我们使用 Next.js API Routes 来创建后端接口,在 /pages/api/posts/ 下创建几个接口:

GET /api/posts - 获取所有博客文章

// /pages/api/posts/index.ts
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  if (req.method === 'GET') {
    const posts = await prisma.post.findMany();
    return res.status(200).json(posts);
  }
  res.status(405).end(); // Method Not Allowed
}

POST /api/posts - 创建新博客文章

// /pages/api/posts/index.ts
export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { title, body } = req.body;
    const newPost = await prisma.post.create({
      data: { title, body }
    });
    return res.status(201).json(newPost);
  }
  res.status(405).end(); // Method Not Allowed
}

GET /api/posts/[id] - 获取指定 ID 的博客文章

// /pages/api/posts/[id].ts
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  const { id } = req.query;

  if (req.method === 'GET') {
    const post = await prisma.post.findUnique({
      where: { id: Number(id) },
    });
    if (!post) return res.status(404).json({ message: 'Post not found' });
    return res.status(200).json(post);
  }
  res.status(405).end(); // Method Not Allowed
}

PUT /api/posts/[id] - 更新博客文章

// /pages/api/posts/[id].ts
export default async function handler(req, res) {
  const { id } = req.query;

  if (req.method === 'PUT') {
    const { title, body } = req.body;
    const updatedPost = await prisma.post.update({
      where: { id: Number(id) },
      data: { title, body },
    });
    return res.status(200).json(updatedPost);
  }
  res.status(405).end(); // Method Not Allowed
}

DELETE /api/posts/[id] - 删除博客文章

// /pages/api/posts/[id].ts
export default async function handler(req, res) {
  const { id } = req.query;

  if (req.method === 'DELETE') {
    await prisma.post.delete({
      where: { id: Number(id) },
    });
    return res.status(204).end(); // No content
  }
  res.status(405).end(); // Method Not Allowed
}

4. 前端实现

首页展示文章(SSG)

/pages/index.tsx

import { GetStaticProps } from 'next';
import Link from 'next/link';

const Home = ({ posts }) => {
  return (
    <div>
      <h1>全栈博客</h1>
      <ul>
        {posts.map(post => (
          <li key={post.id}>
            <Link href={`/blog/${post.id}`}>{post.title}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
};

export const getStaticProps: GetStaticProps = async () => {
  const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/posts`);
  const posts = await res.json();

  return { props: { posts } };
};

export default Home;

博客详情页(ISR)

/pages/blog/[id].tsx

import { GetStaticPaths, GetStaticProps } from 'next';

const Post = ({ post }) => {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </div>
  );
};

export const getStaticPaths: GetStaticPaths = async () => {
  const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/posts`);
  const posts = await res.json();

  const paths = posts.map(post => ({ params: { id: post.id.toString() } }));

  return { paths, fallback: 'blocking' };
};

export const getStaticProps: GetStaticProps = async ({ params }) => {
  const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/posts/${params.id}`);
  const post = await res.json();

  return { props: { post }, revalidate: 10 }; // 每10秒刷新一次
};

export default Post;

5. 完整的开发环境和部署

  • 本地环境:使用 Docker 启动 MySQL,配合 Prisma 操作数据库

  • 部署:使用 Vercel 部署 Next.js 应用,MySQL 可以使用 PlanetScaleVercel MySQL 作为数据库

image.png

本文来自E先生的博客,如若转载,请注明出处:https://javajz.cn

留言区

联系人:
手   机:
内   容:
验证码:

历史留言

欢迎加Easy的QQ