#nextjs 12 with third party server
1 messages · Page 1 of 1 (latest)
在 Next.js 12 使用第三方 server(如 Koa)時,於 pages/index.js 的 getServerSideProps 取得 server 資料的最佳實踐如下:
-
直接在 getServerSideProps 內呼叫第三方 API 或資料庫
getServerSideProps 只會在 server 端執行,不會被打包到 client,因此你可以安全地在這裡直接呼叫 Koa server 提供的 API 或資料庫,不需透過 Next.js API Route 做中介。
範例:// pages/index.js export async function getServerSideProps() { // 直接呼叫 Koa server 的 API const res = await fetch('<http://localhost:3001/api/data'>) // 假設 Koa server 跑在 3001 port const data = await res.json() return { props: { data }, // 傳遞給 Page component } } export default function Page({ data }) { return <div>{JSON.stringify(data)}</div> }這樣做的好處是效能最佳化,且不會將 server-only 依賴打包到 client 端。
參考:getServerSideProps 官方文件 -
錯誤處理
若呼叫 Koa server 發生錯誤,建議在 catch 區塊回傳空資料或導向錯誤頁面:export async function getServerSideProps() { try { const res = await fetch('<http://localhost:3001/api/data'>) const data = await res.json() return { props: { data } } } catch (error) { // 可選擇回傳空資料或導向 404/500 return { props: { data: null } } } } -
何時使用 getServerSideProps
當你需要每次請求都取得最新資料(如個人化、即時資料),才建議用 getServerSideProps。如果資料可快取,建議用 getStaticProps 或 ISR 以提升效能。
參考:getServerSideProps 說明
總結:
直接在 getServerSideProps 內呼叫 Koa server API 是 Next.js 12 的最佳實踐,確保效能與安全性,並妥善處理錯誤與資料快取需求。
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@sonic ruin Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@silver thicket 在 getServerSideProps 中取得後端資料的最佳實踐是 call api 嗎
那如果是用 call server 中的 service 呢
Let me check the knowledge base for you again. Give me one moment! :books:
在 Next.js 的 getServerSideProps 中取得後端資料時,最佳實踐是直接呼叫 server-side 的 service 或資料庫,而不是透過 HTTP API call 自己的 server。
根據官方文件,getServerSideProps 只會在 server 端執行,因此你可以直接在這個 function 內呼叫本地的 service、資料庫或 ORM,這樣可以避免多餘的 HTTP 請求,提升效能。例如:
// pages/index.js
import { getDataFromService } from '../lib/service'
export async function getServerSideProps() {
const data = await getDataFromService()
return { props: { data } }
}
官方建議:
你不需要在 getServerSideProps 裡面 call Next.js API Route 來取得資料,因為這個 function 已經在 server 執行,可以直接呼叫 CMS、資料庫或第三方 API【直接呼叫 service】來源.
另外,Vercel 也有相關建議,指出如果你在 getServerSideProps 裡面用 fetch call 自己的 API route,會造成多一次不必要的網路請求,建議直接共用 service function 來取得資料來源。
總結:
- 若是要取得自己 server 的資料,最佳實踐是直接呼叫本地的 service function 或資料庫,不要用 fetch call 自己的 API。
- 只有在需要跨 server 或第三方 API 時,才用 fetch。
這樣可以確保效能最佳且架構清晰。
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@sonic ruin Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@silver thicket 對 我在 Next.js 12 中是以 koa 代替 nextjs 的 server,所以我該如何做 getDataFromService 的內容會長怎樣
Let me check the knowledge base for you again. Give me one moment! :books:
在 Next.js 12 中以 Koa 取代 Next.js 的 server 時,getServerSideProps 仍然只會在 server 端執行。
根據官方文件,最佳實踐是直接呼叫本地的 service function(例如存取資料庫),而不是透過 HTTP API call 自己的 server。
你可以將 service function 實作在 lib/ 目錄下,然後在 getServerSideProps 直接 import 並呼叫。
範例:
// lib/service.js
export async function getDataFromService() {
// 這裡可以直接存取資料庫或其他本地資源
// 例如:return await db.query('SELECT * FROM users')
return [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
}
// pages/index.js
import { getDataFromService } from '../lib/service'
export async function getServerSideProps() {
const data = await getDataFromService()
return { props: { data } }
}
export default function Page({ data }) {
return (
<ul>
{data.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
重點:
- getDataFromService 內容可以直接存取資料庫、檔案系統或其他本地資源,不需要透過 HTTP 請求。
- 這樣做效能最佳,也符合 Next.js 官方建議【參考來源】Write server-side code directly.
如果你必須要透過 Koa 的 context 或 middleware 提供的某些功能,則需確保這些功能能在 getServerSideProps 執行時被呼叫到。不過,官方文件並未提供與 Koa 深度整合的細節,因此這部分需依你的專案架構自行設計。
總結:
getDataFromService 內容就是直接存取你 server 端可用的資源,不需經過 HTTP API call。
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@sonic ruin Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@silver thicket 如果 service() 和 searchList 想要共用邏輯呢
api:
exports.searchResults = async ctx => {
const data = service()
ctx.status = 200
ctx.response.body = {
status: 200,
data,
}
}
page:
const SearchPage = () => {
return (
<>
<Layout>
<Search />
</Layout>
)}
</>
)
}
export const getServerSideProps = wrapper.getServerSideProps(async ({ store, query }) => {
const data = await searchList(query)
return {}
})
Let me check the knowledge base for you again. Give me one moment! :books:
根據 Next.js 官方最佳實踐,共用邏輯(如 service function)應該抽離到一個共用的 module(例如 lib/service.js),然後在 API route(Koa handler)和 getServerSideProps 兩邊都直接 import 這個 function 來使用,而不是透過 HTTP call 來共用邏輯。這樣可以避免多餘的網路請求並提升效能。
你的架構可以這樣設計:
1. 抽離共用邏輯到 lib/service.js:
// lib/service.js
export async function searchList(query) {
// 這裡寫共用的查詢邏輯,例如查資料庫
// return await db.search(query)
return [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
}
2. Koa API handler 直接呼叫共用邏輯:
// api/search.js
const { searchList } = require('../lib/service')
exports.searchResults = async ctx => {
const data = await searchList(ctx.query)
ctx.status = 200
ctx.response.body = {
status: 200,
data,
}
}
3. getServerSideProps 也直接呼叫共用邏輯:
// pages/search.js
import { searchList } from '../lib/service'
export const getServerSideProps = async ({ query }) => {
const data = await searchList(query)
return { props: { data } }
}
這樣做的好處:
- 效能最佳:避免 HTTP 請求自己 server。
- 維護性高:邏輯集中,易於維護與測試。
這正是 Next.js 官方推薦的做法:「Instead of fetching your /api route you can call the same function directly in getStaticProps(或 getServerSideProps)」來源
Vercel 也有同樣建議:來源