javascript - 使用 getServerSideProps 获取内部 API?(Next.js)
问题描述
我是 Next.js 的新手,我正在尝试了解建议的结构并处理页面或组件之间的数据。
例如,在我的页面home.js
中,我获取了一个调用的内部 API /api/user.js
,它从 MongoDB 中返回一些用户数据。我通过使用fetch()
从内部调用 API 路由来做到这一点getServerSideProps()
,它在一些计算后将各种道具传递到页面。
据我了解,这对 SEO 有好处,因为道具在服务器端被获取/修改,并且页面让它们准备好呈现。fetch()
但后来我在Next.js文档中读到,你不应该使用getServerSideProps()
. 那么我应该怎么做才能遵守良好的做法和良好的 SEO?
我没有home.js
在 API 路由本身中进行所需计算的原因是我需要来自这个 API 路由的更多通用数据,因为我也会在其他页面中使用它。
我还必须考虑缓存,客户端使用 SWR 获取内部 API 非常简单,但服务器端我还不确定如何实现它。
home.js
:
export default function Page({ prop1, prop2, prop3 }) {
// render etc.
}
export async function getServerSideProps(context) {
const session = await getSession(context)
let data = null
var aArray = [], bArray = [], cArray = []
const { db } = await connectToDatabase()
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
if (session) {
const hostname = process.env.NEXT_PUBLIC_SITE_URL
const options = { headers: { cookie: context.req.headers.cookie } }
const res = await fetch(`${hostname}/api/user`, options)
const json = await res.json()
if (json.data) { data = json.data }
// do some math with data ...
// connect to MongoDB and do some comparisons, etc.
解决方案
fetch()
但后来我在Next.js文档中读到,你不应该使用getServerSideProps()
.
您想直接使用 API 路由中的逻辑getServerSideProps
,而不是调用内部 API。那是因为getServerSideProps
就像 API 路由一样在服务器上运行(从服务器向服务器本身发出请求是没有意义的)。您可以从文件系统读取或直接从getServerSideProps
.
来自 Next.jsgetServerSideProps
文档:
当您想从服务器获取数据时,可能很容易使用 API 路由,然后从
getServerSideProps
. 这是一种不必要且低效的方法,因为它会由于getServerSideProps
服务器上运行的 API 路由和 API 路由而导致发出额外的请求。(...) 相反,直接将 API Route 中使用的逻辑导入
getServerSideProps
. 这可能意味着直接从内部调用 CMS、数据库或其他 APIgetServerSideProps
。
(请注意,使用getStaticProps
/getStaticPaths
方法时同样适用)
这是一个小的重构示例,它允许您在getServerSideProps
.
假设您有这个简单的 API 路由。
// pages/api/user
export default async function handler(req, res) {
// Using a fetch here but could be any async operation to an external source
const response = await fetch(/* external API endpoint */)
const jsonData = await response.json()
res.status(200).json(jsonData)
}
您可以将获取逻辑提取到一个单独的函数中(api/user
如果需要,仍然可以保留它),它仍然可以在 API 路由中使用。
// pages/api/user
export async function getData() {
const response = await fetch(/* external API endpoint */)
const jsonData = await response.json()
return jsonData
}
export default async function handler(req, res) {
const jsonData = await getData()
res.status(200).json(jsonData)
}
而且还允许你重复getData
使用getServerSideProps
.
// pages/home
import { getData } from './api/user'
//...
export async function getServerSideProps(context) {
const jsonData = await getData()
//...
}
推荐阅读
- typescript - 基于键大小写的 TypeScript 类型
- firebase - Firebase 的实例属性是函数吗?
- r - 生成 R 闪亮仪表板时出错:警告:choiceWithNames 中的错误
- flutter - 如何使 showGeneralDialog() 关闭动画与打开动画不同?
- python - 调用 os.rename() 时出错:“该进程无法访问该文件,因为它正被另一个进程使用”
- flutter - StreamBuilder总是在flutter中的print(snapshot.hasData)中返回false
- amazon-cloudwatch - AWS Cloudwatch 指标值重置
- sqlite - SQLite:单行插入/更新 ACID?
- django - Django模型不同实现的比较数据库指标
- css - Blazor 模板/布局,包括不同模板/布局的不同 javascript 库