Next.js v14(App Router+Server Components)API结构如何设计?
关于Next.js API逻辑结构的澄清与最佳实践
首先纠正你的误解:文档里提到的嵌套在页面路由下的api/route.ts是前端对外暴露的API端点,不是让你把核心业务逻辑写死在这里。你觉得会重复是因为没做逻辑抽离——这些Route Handler只是个"入口",真正的API调用逻辑应该单独封装,实现全局复用。
一、服务端组件全局API逻辑的最佳结构
在项目根目录创建lib/或services/文件夹,把调用第三方API的核心逻辑封装成独立函数,比如:
创建lib/external-api.ts:
export async function fetchRandomData() { const res = await fetch('https://random-api.com/...', { // 这里可放置服务端专属配置,比如用环境变量存储密钥 headers: { Authorization: `Bearer ${process.env.EXTERNAL_API_KEY}` } }) if (!res.ok) { throw new Error('请求第三方API失败') } return res.json() }
之后不管是在/app/dashboard/page.tsx(服务端组件)还是其他服务端组件里,直接导入调用即可:
import { fetchRandomData } from '@/lib/external-api' export default async function DashboardPage() { const data = await fetchRandomData() return <div>{JSON.stringify(data)}</div> }
如果需要给客户端组件提供API接口,再在对应路由下创建api/route.ts,内部调用封装好的函数:
import { fetchRandomData } from '@/lib/external-api' export async function GET() { try { const data = await fetchRandomData() return Response.json({ data }) } catch (error) { return Response.json({ error: '获取数据失败' }, { status: 500 }) } }
二、客户端组件能否复用相同的API函数?
分两种情况处理:
- 如果封装的函数是纯客户端友好的请求(比如调用无需密钥的第三方公开API),可以直接在客户端组件导入调用,但要注意跨域问题——若第三方API未开启CORS,仍需通过前端API端点代理请求。
- 如果函数包含服务端专属逻辑(比如访问环境变量密钥、操作数据库),绝对不能在客户端组件中使用——因为客户端代码会被打包到浏览器,密钥等敏感信息会泄露。此时客户端组件应调用前端的API端点(即你创建的
api/route.ts),由服务端执行封装好的逻辑。
举个客户端组件的示例:
'use client' import { useEffect, useState } from 'react' export default function ClientComponent() { const [data, setData] = useState(null) useEffect(() => { async function getData() { const res = await fetch('/dashboard/api') const result = await res.json() setData(result.data) } getData() }, []) return <div>{data ? JSON.stringify(data) : '加载中...'}</div> }
内容的提问来源于stack exchange,提问作者JBrown
相关产品推荐
相关产品推荐

