Internal API fetch with getServerSideProps? (Next.js)

主宰稳场 提交于 2021-02-08 09:08:03

问题


I'm new to Next.js and I'm trying to understand the suggested structure and dealing with data between pages or components.

For instance inside my home.js page, I fetch a internal API called /api/user.js where it sends back to me some user data from mongodb. The fetch right now happens inside the getServerSideProps() which passes various props to the page after some math.

From my understanding this is the way to go for a good SEO, since props get fetched/modified server side and the page gets em ready to render. But then I read in the Next.js documentation that fetch to internal API shouldn't happen inside the getServerSideProps() .. so what am I suppose to do to comply to good practice and good SEO?

The reason I'm not doing also the home.js math inside the /api/user.js and THEN pass data to home.js, is because I need more generic data from /api/user.js which I use differently in other pages as well.

Not to mention the caching aspect, which client side is very straight forward using SWR to fetch an internal API, but server side I'm not yet sure how to achieve it.

home.js snippet:

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.

回答1:


But then I read in the Next.js documentation that fetch to internal API shouldn't happen inside the getServerSideProps()

You'd want to use the logic that's in your API route directly in getServerSideProps, rather than calling your internal API.

Here's a small refactor example that allows you to have logic from an API route reused in getServerSideProps.

Let's assume you have this simple API route.

// 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)
}

You can extract the fetching logic to a separate function (can still keep it in api/user if you want), which is still usable in the API route.

// 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)
}

But also allows you to re-use the getData function in getServerSideProps.

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

//...

export async function getServerSideProps(context) {
    const jsonData = await getData()
    //...
}


来源:https://stackoverflow.com/questions/65752932/internal-api-fetch-with-getserversideprops-next-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!