Next.js 14(以及自Next.js 13开始)引入了app
目录和新的路由方式,包括API路由的编写方式也发生了一些变化。虽然pages
目录仍然受支持,但app
目录提供了一种更现代化的方式来处理路由和API。
编写api接口文件
在app
目录中 ,每个子目录对应一个路由,route.js
文件用于处理API请求,而页面组件文件(通常为page.js
或page.tsx
)用于处理页面渲染。
例如创建两个接口,需要在 app
目录下api
创建文件夹(访问接口名) 下场景 route.ts
即可
app/ ├── api/ │ ├── hello/ │ │ └── route.js # 对应路径 /api/hello │ └── submit/ │ └── route.js # 对应路径 /api/submit
对应访问:
- http://localhost:3000/api/hello
- http://localhost:3000/api/submit
复杂
页面+API 文件结构
如果想 同时处理前端页面的渲染和后端API ,结果如下:
app/ ├── api/ │ ├── hello/ │ │ └── route.js # 对应路径 /api/hello │ ├── submit/ │ │ └── route.js # 对应路径 /api/submit │ └── users/ │ └── route.js # 对应路径 /api/users ├── page.js # 根路径的页面文件,对应路径 / ├── about/ │ └── page.js # 关于页面的文件,对应路径 /about ├── users/ │ ├── page.js # 用户页面的文件,对应路径 /users │ └── [id]/ │ └── page.js # 动态路由页面文件,对应路径 /users/[id]
完整 CURD API 编写
文件结构
app/ ├── api/ │ ├── users/ │ │ ├── route.js # 处理GET、POST请求 │ │ └── [id]/ │ │ └── route.js # 处理单个用户的GET、PUT、DELETE请求 ├── users/ │ ├── page.js # 用户列表页面,展示所有用户 │ └── [id]/ │ └── page.js # 用户详情页面,展示单个用户信息 ├── page.js # 根路径的页面文件 └── layout.js # 布局文件
API 路由
下面是使用的Mogodb 数据库,这块可以自己业务选型数据库使用
GET POST 请求
app/ ├── api/ │ ├── users/ │ │ ├── route.js # 处理GET、POST请求
// app/api/users/route.js import clientPromise from '@/lib/mongodb'; import { NextResponse } from 'next/server'; // 处理GET请求,返回所有用户 export async function GET() { const client = await clientPromise; const db = client.db('mydatabase'); const users = await db.collection('users').find({}).toArray(); return NextResponse.json(users); } // 处理POST请求,创建新用户 export async function POST(request) { const client = await clientPromise; const db = client.db('mydatabase'); const data = await request.json(); // 验证输入数据 if (!data.name || !data.email) { return NextResponse.json({ message: 'Name and Email are required' }, { status: 400 }); } // 插入新用户 const result = await db.collection('users').insertOne(data); return NextResponse.json(result.ops[0], { status: 201 }); }
动态api [获取详情, 更新数据, 删除数据]
app/ ├── api/ │ ├── users/ │ │ ├── route.js # 处理GET、POST请求 │ │ └── [id]/ │ │ └── route.js # 处理单个用户的GET、PUT、DELETE请求
通过定义动态文件 app/api/users/[id]/route.js
分别定义3个方法来处理对应请求业务
- GET: 获取详情
- PUT: 更新数据
- DELETE: 删除数据
// app/api/users/[id]/route.js import clientPromise from '@/lib/mongodb'; import { ObjectId } from 'mongodb'; import { NextResponse } from 'next/server'; // 处理GET请求,获取单个用户的信息 export async function GET(request, { params }) { const client = await clientPromise; const db = client.db('mydatabase'); const user = await db.collection('users').findOne({ _id: new ObjectId(params.id) }); if (!user) { return NextResponse.json({ message: 'User not found' }, { status: 404 }); } return NextResponse.json(user); } // 处理PUT请求,更新用户的信息 export async function PUT(request, { params }) { const client = await clientPromise; const db = client.db('mydatabase'); const data = await request.json(); // 更新用户数据 const result = await db.collection('users').updateOne( { _id: new ObjectId(params.id) }, { $set: data } ); if (result.matchedCount === 0) { return NextResponse.json({ message: 'User not found' }, { status: 404 }); } const updatedUser = await db.collection('users').findOne({ _id: new ObjectId(params.id) }); return NextResponse.json(updatedUser); } // 处理DELETE请求,删除用户 export async function DELETE(request, { params }) { const client = await clientPromise; const db = client.db('mydatabase'); const result = await db.collection('users').deleteOne({ _id: new ObjectId(params.id) }); if (result.deletedCount === 0) { return NextResponse.json({ message: 'User not found' }, { status: 404 }); } return NextResponse.json({ message: 'User deleted successfully' }); }