Next.js App Router 的主路线非常明确:
- 首屏数据,优先在 Server Component 里取
- 能直接读数据库或内部服务,就别先绕去浏览器
- 能少一次 HTTP 往返,就少一次
// app/orders/page.tsx
async function getOrders() {
const res = await fetch('https://example.com/api/orders');
if (!res.ok) throw new Error('加载订单失败');
return res.json();
}
export default async function OrdersPage() {
const orders = await getOrders();
return (
<ul>
{orders.map((order: { id: string; status: string }) => (
<li key={order.id}>
#{order.id} - {order.status}
</li>
))}
</ul>
);
}如果你有数据库访问能力,更理想的是直接这样:
// app/orders/page.tsx
import { db } from '@/lib/db';
export default async function OrdersPage() {
const orders = await db.order.findMany();
return (
<ul>
{orders.map(order => (
<li key={order.id}>
#{order.id} - {order.status}
</li>
))}
</ul>
);
}#别在 Server Component 里再去请求自己家的 Route Handler
这是 Next.js 官方文档里很明确的一条工程建议:
如果你已经在服务端了,就不要再 fetch('/api/xxx') 绕一圈打回自己。
错误心智:
Server Component
↓
请求自己 app 里的 /api/products
↓
Route Handler
↓
数据库更直接的心智:
Server Component
↓
数据库 / 内部服务前者多了一次无意义的网络跳转、序列化和部署耦合。