使用 getServerSideProps 获取内部 API?(下一个.js)

m4t*_*4tt 9 javascript node.js fetch-api server-side-rendering next.js

我是 Next.js 的新手,我正在尝试理解建议的结构并处理页面或组件之间的数据。

例如,在我的页面中home.js,我获取了一个调用的内部 API /api/user.js,它从 MongoDB 返回一些用户数据。我通过使用fetch()从 inside 调用 API 路由来做到这一点getServerSideProps(),它在一些计算后将各种道具传递给页面。

根据我的理解,这对 SEO 有好处,因为道具在服务器端被获取/修改,页面让它们准备好呈现。但后来我的Next.js文档,你不应该用在阅读fetch()到所有的API路线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.
Run Code Online (Sandbox Code Playgroud)

jul*_*ves 18

但后来我的Next.js文档,你不应该用在阅读fetch()到所有的API路线getServerSideProps()

您希望直接在 中使用 API 路由中的逻辑getServerSideProps,而不是调用内部 API。

(请注意,使用getStaticProps/ getStaticPathsmethods时同样适用


这是一个小型重构示例,它允许您在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)
}
Run Code Online (Sandbox Code Playgroud)

您可以将获取逻辑提取到一个单独的函数中(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)
}
Run Code Online (Sandbox Code Playgroud)

而且还允许您getDatagetServerSideProps.

// pages/home
import { getData } from './api/user'

//...

export async function getServerSideProps(context) {
    const jsonData = await getData()
    //...
}
Run Code Online (Sandbox Code Playgroud)

  • 爆炸!沮丧了一整天,发现这终于可以立即将数据放入框中!为什么 api/routes 不直接为什么需要以其他方式提供它,他们采取了什么样的方法来构建,我不明白!一切都是为了满足我们头脑中的创造!抱歉,这可能是我令人沮丧的评论! (4认同)
  • 这很奇怪,从其他优秀的文档中并不清楚这一点 (3认同)
  • 导出函数是我在其他需要可重用函数的地方也需要的,但没有人建议我以这种方式导出它,谢谢,我会尝试一下 (2认同)
  • @Roi不仅仅是导出函数,只有在客户端代码中使用该函数时它才会暴露。 (2认同)