nextjs学习4:创建服务端 API(路由处理程序)

前后端分离架构中,客户端与服务端之间通过 API 接口来交互。这个API 接口在 Next.js 中有个更为正式的称呼,就是路由处理程序。

定义路由处理程序

写路由处理程序,你需要定义一个名为 route.js的特殊文件。(注意是 route 不是 router)

该文件必须在 app目录下,可以在 app 嵌套的文件夹下,但是要注意 page.js和 route.js不能在同一层级同时存在。

想想也能理解,page.js和 route.js本质上都是对路由的响应。page.js主要负责渲染 UI,route.js主要负责处理请求。如果同时存在,Next.js 就不知道用谁的逻辑了。

GET 请求

让我们从写 GET 请求开始,比如写一个获取文章列表的接口。

新建 app/api/posts/route.js 文件,代码如下:

js 复制代码
import { NextResponse } from 'next/server'
 
export async function GET() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()
 
  return NextResponse.json({ data })
}

浏览器访问 http://localhost:3000/api/posts 查看接口返回的数据:

在这个例子中:

  1. 我们 export 一个名为 GET 的 async 函数来定义 GET 请求处理,注意是 export 而不是 export default

  2. 我们使用 next/server 的 NextResponse 对象用于设置响应内容,但这里不一定非要用 NextResponse,直接使用 Response 也是可以的。

  3. 我们将接口写在了 app/api 文件夹下,并不是因为接口一定要放在名为 api 文件夹下。如果你代码写在 app/posts/route.js,对应的接口地址就是 /posts。放在 api 文件夹下只是为了方便区分地址是接口还是页面。

但在实际开发中,推荐使用 NextResponse,因为它是 Next.js 基于 Response 的封装,它对 TypeScript 更加友好,同时提供了更为方便的用法,比如获取 Cookie 等。

支持方法

Next.js 支持 GET、POST、PUT、PATCH、DELETE、HEAD 和 OPTIONS 这些 HTTP 请求方法。如果传入了不支持的请求方法,Next.js 会返回 405 Method Not Allowed。

js 复制代码
// route.js
export async function GET(request) {}
 
export async function HEAD(request) {}
 
export async function POST(request) {}
 
export async function PUT(request) {}
 
export async function DELETE(request) {}
 
export async function PATCH(request) {}
 
// 如果 `OPTIONS` 没有定义, Next.js 会自动实现 `OPTIONS`
export async function OPTIONS(request) {}

继续修改 app/api/posts/route.js,添加代码如下:

js 复制代码
export async function POST(request) {
  const article = await request.json()
  
  return NextResponse.json({
    id: Math.random().toString(36).slice(-8),
    data: article
  }, { status: 201 })
}

传入参数

现在让我们具体看下请求方法。每个请求方法的处理函数会被传入两个参数,一个 request,一个 context 。两个参数都是可选的:

js 复制代码
export async function GET(request, context) {}

request 对象是一个 NextRequest 对象,它是基于 Web Request API 的扩展。使用 request ,你可以快捷读取 cookies 和处理 URL。

我们这里讲讲如何获取 URL 参数:

js 复制代码
export async function GET(request, context) {
  //  访问 /home, pathname 的值为 /home
  const pathname = request.nextUrl.pathname
  // 访问 /home?name=lee, searchParams 的值为 { 'name': 'lee' }
  const searchParams = request.nextUrl.searchParams
}

其中 nextUrl 是基于 Web URL API 的扩展(如果你想获取其他值,参考 URL API),同样提供了一些方便使用的方法。

context (optional)

目前context 只有一个值就是 params,它是一个包含当前动态路由参数的对象。举个例子:

js 复制代码
// app/dashboard/[team]/route.js
export async function GET(request, { params }) {
  const team = params.team
}

示例代码:

需求:目前 GET 请求 /api/posts 时会返回所有文章数据,现在希望 GET 请求 /api/posts/1?dataField=title 获取 post id 为 1 的文章数据,dataField 用于指定返回哪些字段数据。

新建 /api/posts/[id]/route.js,代码如下:

js 复制代码
import { NextResponse } from 'next/server'

export async function GET(request, { params }) {
  const field = request.nextUrl.searchParams.get("dataField")
  const data = await ((await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`)).json())
  const result = field ? { [field]: data[field] } : data
  return NextResponse.json(result)
}

现在有了服务端 API ,客户端组件也可以使用 axios 或 fetch 来请求数据了。

相关推荐
FungLeo1 天前
成为全栈·Next.js 网站前台篇·响应式、可访问性与错误状态:内容站不能只验桌面首页
react.js·响应式设计·next.js·移动端适配·成为全栈·web 可访问性
FungLeo1 天前
成为全栈·Next.js 网站前台篇·站点设置如何驱动页头、页脚与 SEO
react·isr·next.js·metadata·成为全栈·站点配置
FungLeo4 天前
成为全栈·Next.js 网站前台篇·同源 BFF 代理:API、附件、Cookie 与跨站写入保护
react·csrf·next.js·bff·成为全栈·route handler
FungLeo4 天前
成为全栈·Next.js 网站前台篇·评论系统:叠楼、回复、删除与内容审核如何落到前台
react.js·内容审核·next.js·评论系统·树形数据·成为全栈
cindershade7 天前
一条请求的接力赛:用运行时责任重画 RSC 边界
性能优化·next.js
zach8 天前
前端落地实战:Next.js 项目 Nginx + PM2 生产部署全流程(附踩坑总结)
前端·pm2·next.js
zach8 天前
Vue/React SPA 打包部署后,子路由刷新 401 未登录问题彻底解决
前端·nginx·next.js
FungLeo10 天前
成为全栈·Next.js 网站前台篇·数据获取与缓存:60 秒再验证背后到底发生了什么
react·isr·next.js·成为全栈·react cache·opennext
名字还没想好☜18 天前
React 文件上传实战:预览 URL 回收、多文件逐个进度与拖拽放置区踩坑
前端·react·next.js
moMo1 个月前
NestJS 入门:用"模块化 + 装饰器"读懂大型后端框架
next.js