Copyright © 2008 ~ 2024 MUKI space* / omegaBook theme All Rights Reserved.

簡介與緣起

在開發 Web 應用程式時,我們經常需要從伺服器端取得資料。這通常涉及到呼叫 API 並處理回傳的資料。在 JavaScript 中,我們有許多方法可以呼叫 API,其中最常見的兩種方法是使用 fetch() 和 axios。然而,當我們在使用 Next.js 的 Server Components 時,我們應該選擇哪一種方法呢?

會有這疑問,是因為我在撰寫 Next.js 串接 TradingView 開發的圖表套件,並透過 Server 端呼叫外部的富果 API 這篇文章時,原本用的是 axios 呼叫 api,但牽扯到使用 Server Components 時,究竟用哪一種呼叫方式能對後端資料有更好的優化?因此整理了一些內容跟想法,分享給大家。

fetch() 與 axios 的差異

fetch() 和 axios 都是用來在 JavaScript 中發送 HTTP 請求的函式庫。它們都可以用來呼叫 API 並取得資料。然而,它們在使用方式和功能上有一些差異:

  • fetch() 是一種內建在大多數現代瀏覽器中的函式,它提供了一種簡單、原生的方式來發送 HTTP 請求。fetch() 支援 Promise 和 async/await 語法,使得非同步操作變得更加容易。
  • axios 是一種第三方函式庫,它提供了一些 fetch() 沒有的額外功能,例如監聽請求進度,以及自動轉換 JSON 資料

使用 fetch() 的好處

雖然用 axios 比 fetch() 更方便也更容易理解,但 Next.js 的 Server Components 有針對 fetch() 語法進行以下優化:

  • 自動記憶 fetch 請求:Next.js 會在伺服器端自動記憶 fetch 請求,並在渲染 React 元件樹時擴展 fetch。所以我們可以在 Server Component、Route Handlers、和 Server Actions 中使用 fetch 與 async / await。
  • 資料快取:Next.js 會自動將 fetch 的回傳值快取在伺服器端的 Data Cache 中。這意味著資料可以在建置時間或請求時間被取得,並在每次資料請求時被重複使用。
  • 資料重新驗證:重新驗證是清除 Data Cache 並重新取得最新資料的過程。如果我們需要變更資料,並確保變更後會顯示最新資訊的話,這個功能能幫助我們。

因此如果要使用 Server Components,也許可以視情況改用 fetch()。

參考資料

  1. Data Fetching, Caching, and Revalidating / Nextjs.org

從 axios 切換到 fetch()

我使用在 Next.js 串接 TradingView 開發的圖表套件,並透過 Server 端呼叫外部的富果 API 呼叫股票 API 的語法,跟大家分享該怎麼從 axios 切換到 fetch()

▼ 原本的 axios 語法

export async function fetchTSEIndex() {
  try {
    const headers = {
      'X-API-KEY': process.env.API_KEY as string,
      'Content-Type': 'application/json'
    }
    const payload = {
      fields: 'open,high,low,close,volume'
    }
    const response = await axios.get(apiTSEIndexUrl, {
      headers: headers,
      params: payload,
    })
    return response.data.data
  } catch (error) {
    console.error('error:', error)
  }
}

▼ 改用 fetch() 呼叫 API,需注意三點:(1) fetch() 要額外將回傳資料轉成 JSON 格式,(2) 需要使用 URLSearchParams() 函式處理網址的參數,(3) 錯誤處理方式(詳見下一段說明)

export async function fetchTSEIndex() {
  try {
    const headers = {
      'X-API-KEY': process.env.API_KEY,
      'Content-Type': 'application/json'
    }
    // 使用 URLSearchParams()
    const payload = new URLSearchParams({
      fields: 'open,high,low,close,volume'
    })
    const response = await fetch(`${apiTSEIndexUrl}?${payload}`, {
      headers: headers,
    })
    if (!response.ok) {
      // 處理錯誤
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    // 處理 JSON 格式資料
    const data = await response.json()
    return data.data
  } catch (error) {
    console.error('error:', error)
  }
}

fetch() 的錯誤處理方式

fetch() 只有在網路錯誤時才會拋出異常,而不是在 HTTP 錯誤狀態碼 (HTTP status code)時。因此,我們需要檢查 response.ok 來確定是否有 HTTP 錯誤。如果有,我們就拋出一個錯誤。

結論

在 Next.js 的 Server Components 中,可以選擇使用 fetch() 或 axios 來呼叫 API。然而,Next.js 的 Server Component 功能有針對 fetch() 進行優化,因此使用 fetch() 可能會有更好的效果。然而,這並不意味著你不能使用 axios 或其他第三方函式庫。我們應該根據網站需求和偏好來選擇最適合的方法。

如果有任何問題,都歡迎告訴我,謝謝!

歡迎給我點鼓勵,讓我知道你來過 :)

2
2
1
Subscribe
Notify of
guest

2 則留言
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
david
david
3 months ago