首页 > 解决方案 > 如何从`getStaticProps`向API路由发出请求

问题描述

我想在网站上显示来自 YouTube 频道的最新视频。该频道每天最多上传一次,因此我将 API 路由的响应缓存了 1 天(86400 秒),vercel.json如下所示

{
    "headers": [
        {
            "source": "/(.*)",
            "headers": [
                {
                    "key": "access-control-allow-origin",
                    "value": "*"
                },
                {
                    "key": "Cache-Control",
                    "value": "s-maxage=86400"
                }
            ]
        }
    ]
}

我想使用getStaticProps增量静态重新生成,以便我的 API 路由每天最多只能发送一次请求,但我不确定如何将请求写入我的 API 路由。

Next.js文档说

注意:您不应该使用fetch()getStaticProps. 相反,直接导入 API 路由中使用的逻辑。您可能需要针对这种方法稍微重构您的代码。

从外部 API 获取很好!

这是什么意思?我目前编写请求的方法是否错误?

// /pages/index.js

import Header from '../components/header/header'
import MainContent from '../components/main-content/main-content'
import Footer from '../components/footer/footer'

export default function Index({ videoTitle, videoURL, videoThumbnailData }) {
    return (
        <>
            <Header />

            <MainContent
                videoTitle={videoTitle}
                videoURL={videoURL}
                videoThumbnailData={videoThumbnailData}
            />

            <Footer />
        </>
    )
}

// Called at build time, and response revalidated after 1 day (86400 seconds)
// since internal API response is cached on Vercel Edge network for 1 day (see /pages/api/get-latest-video.js)
export async function getStaticProps() {
    // Fetch YouTube videos from internal API route /pages/api/get-latest-video.js
    const res = await fetch(`${process.env.API_ROUTES_URL}/api/get-latest-video`)
    const data = await res.json()

    // Returned as props to page
    return {
        props: {
            videoTitle: data.videoTitle,
            videoURL: data.videoURL,
            videoThumbnailData: data.videoThumbnailData
        },
        revalidate: 86400
    }
}
// /components/main-content/main-content.js

import Section from './section'
import Image from 'next/image'

export default function MainContent({ videoTitle, videoURL, videoThumbnailData }) {
    return (
        <main>
            <Section>
                <a href={videoURL}>
                    {videoTitle}
                </a>
                <Image
                    src={videoThumbnailData.url}
                    width={videoThumbnailData.width}
                    height={videoThumbnailData.height}
                />
            </Section>
        </main>
    )
}

标签: javascriptreactjsapinext.jsvercel

解决方案


这意味着您只需将 api 函数导入 getStaticProps 而不是使用 Fetch

// /pages/index.js

import Header from "../components/header/header";
import MainContent from "../components/main-content/main-content";
import Footer from "../components/footer/footer";

export default function Index({ videoTitle, videoURL, videoThumbnailData }) {
  return (
    <>
      <Header />

      <MainContent
        videoTitle={videoTitle}
        videoURL={videoURL}
        videoThumbnailData={videoThumbnailData}
      />

      <Footer />
    </>
  );
}

// Called at build time, and response revalidated after 1 day (86400 seconds)
// since internal API response is cached on Vercel Edge network for 1 day (see /pages/api/get-latest-video.js)
export async function getStaticProps() {
  // Fetch YouTube videos from internal API route /pages/api/get-latest-video.js
  const res = await getApiData(); // import your api function here
  const data = await res.json();

  // Returned as props to page
  return {
    props: {
      videoTitle: data.videoTitle,
      videoURL: data.videoURL,
      videoThumbnailData: data.videoThumbnailData,
    },
    revalidate: 86400,
  };
}


推荐阅读