如何从`getStaticProps`向API路由发出请求
Posted
技术标签:
【中文标题】如何从`getStaticProps`向API路由发出请求【英文标题】:How to make a request to an API route from `getStaticProps` [duplicate] 【发布时间】:2021-05-04 22:51:46 【问题描述】:我想在网站上显示来自 YouTube 频道的最新视频。频道每天最多上传一次,所以我在vercel.json
like so 中缓存了我的 API 路由响应 1 天(86400 秒):
"headers": [
"source": "/(.*)",
"headers": [
"key": "access-control-allow-origin",
"value": "*"
,
"key": "Cache-Control",
"value": "s-maxage=86400"
]
]
我想使用getStaticProps
with incremental static regeneration,这样我的 API 路由每天最多只能收到一次发送请求,但我不确定如何将请求写入我的 API 路由。
Next.js docs say:
注意:您不应使用
fetch()
调用getStaticProps
中的API 路由。相反,直接导入 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>
)
【问题讨论】:
这意味着您应该直接将逻辑导入您的getStaticProps
函数,而不是调用您的内部 API 路由。检查这个答案***.com/questions/65752932/…,它提到了getServerSideProps
,但原理是一样的。
【参考方案1】:
您的请求/api/get-latest-video
应该从浏览器发送到服务器,那么服务器可能有某种路由处理程序,例如:
routeMatches('/api/get-latest-video', ( req, res )=>
requestDB('latestVideos').then( latestVideos =>
respondWithLatestVideos( req, res, latestVideos );
)
);
现在,getStaticProps
在服务器端运行。因此,您可以直接在 getStaticProps
中请求您的数据库,而不是向请求数据库的服务器发送请求。
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()
const data = await requestDB('latestVideos')
...
在同一个 NextJs 文档页面的下方有一条信息更丰富的注释“write server side code directly”:
请注意,
getStaticProps
仅在服务器端运行。它永远不会在客户端运行。它甚至不会包含在浏览器的 JS 包中。这意味着您可以编写诸如直接数据库查询之类的代码,而无需将它们发送到浏览器。您不应该从getStaticProps
获取 API 路由 — 相反,您可以直接在getStaticProps
中编写服务器端代码。
【讨论】:
【参考方案2】:这意味着您只需将您的 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,
;
【讨论】:
以上是关于如何从`getStaticProps`向API路由发出请求的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 API 路由在 Next.JS getStaticProps/getStaticPaths 中构建页面? [复制]
如何从 getstaticprops 函数中的 Context API 获取数据?
如何在 getStaticProps 中获取 slug 值以调用 api,参数为 slug
NextJS:通过上下文将字符串从输入传递到 getStaticProps