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

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

定义路由处理程序

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

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

想想也能理解,page.jsroute.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 一个名为 GETasync 函数来定义 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 支持 GETPOSTPUTPATCHDELETEHEADOPTIONS 这些 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 来请求数据了。

相关推荐
戈德斯文5 天前
我做了一面互联网摸鱼墙:从无限 Canvas 到本地生产环境
react.js·canvas·next.js
三木檾6 天前
从 5 个文件读完一个生产级 AI Chatbot——Vercel AI Chatbot 源码拆解
ai编程·源码阅读·next.js
喵个咪8 天前
基于 Next.js 的 Headless CMS 前端架构:技术解析与二次开发导引
前端·react.js·next.js
倾颜8 天前
React 自定义 Hook 实战:把 AI Chat 的会话流和滚动体验从组件中拆出来
前端·react.js·next.js
竹林81818 天前
用 wagmi v2 + Next.js App Router 踩坑三天,我终于搞定了 NFT 交易市场的跨链签名与上架逻辑
next.js
明月_清风18 天前
全面了解 Vercel:前端开发者的高效武器库与实战指南
前端·next.js
倾颜20 天前
AI 应用里的第一个 Agent:我如何做一个可控的 Tasklist Agent
langchain·agent·next.js
Patrick_Wilson21 天前
IDE 升级重启后 Next.js dev 起不来?kill 无效的真正原因
node.js·next.js·前端工程化
竹林81822 天前
用 wagmi v2 + Next.js 14 搞 NFT 交易市场前端:从合约调用失败到顺利上架,我踩了哪些坑
javascript·next.js
Xinghongia22 天前
手把手教你搭建一个基于 Next.js 16 + FastAPI 构建的高颜值前后端分离个人博客
next.js