#nextjs 12 with third party server

1 messages · Page 1 of 1 (latest)

silver thicketBOT
#

Hi @sonic ruin. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

在 Next.js 12 使用第三方 server(如 Koa)時,於 pages/index.js 的 getServerSideProps 取得 server 資料的最佳實踐如下:

  1. 直接在 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 官方文件

  2. 錯誤處理
    若呼叫 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 return values

  3. 何時使用 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.

sonic ruin
#

@silver thicket 在 getServerSideProps 中取得後端資料的最佳實踐是 call api 嗎
那如果是用 call server 中的 service 呢

silver thicketBOT
#

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.

sonic ruin
#

@silver thicket 對 我在 Next.js 12 中是以 koa 代替 nextjs 的 server,所以我該如何做 getDataFromService 的內容會長怎樣

silver thicketBOT
#

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.

sonic ruin
#

@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 {}
})

silver thicketBOT
#

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 也有同樣建議:來源

總結
將共用邏輯抽離到 module,API handler 和 getServerSideProps 都直接呼叫這個 function,不要用 HTTP call 來共用邏輯。

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: