到底該怎麼串接API?

到底該怎麼串接API?

金流💵、物流🚚、天氣🌤️、新聞📰...這麼多方便的 API 到底該怎麼串接? 這篇將以現實生活中的情境作為範例,幫助你快速、輕鬆的認識並開始串接 API!

串接 API 是系統中非常重要的一環,透過不同的 API 可以讓系統擴充各種由第三方提供的服務、資料,例如政府資料開放平台就提供了非常多的公開資訊開放請求,當然不是所有 API 都免費提供串接,例如金流或物流等專業服務就需要申請、付費才能使用。

前言

不同語言的作法皆有所差異,接下來僅一律以 Javascript 及 RESTful 風格,並以「前往某機構申請資料或服務」的情境作為範例。

快速連結

資源路徑 Resource Path

指的是開放請求、串接的項目,通常也會明確列出該以什麼請求方式進行請求。

請求方式資源路徑提供服務
GET/articles讀取文章列表
GET/articles/{id}讀取單一文章
POST/articles新增文章
PUT/articles/{id}編輯單一文章
DELETE/articles/{id}刪除單一文章

RESTful 風格的 API 主要以請求方式區分行為目的,所以資源路徑看起來幾乎相同是正常的。

請求方式 Method

當我們透過不同的方式發起請求,櫃台人員便能了解此次的行為目的。常見請求方式

  • GET - 讀取
  • POST - 新增
  • PUT / PATCH - 編輯
  • DELETE - 刪除

    簡稱 CRUD,代表 Create(C), Read(R), Update(U), Delete(D)。

    fetch('/example'); // GET 為預設行為
    fetch('/example', {
      method: '...' // 依據自身需求調整
    });

這樣一來便可以成功向 API 發起請求,但是成功發起請求並不代表執行成功,大多數情況下還需要根據需求調整接下來幾章中介紹的項目。

請求標頭 Headers

用以告知 API 此次請求的資訊,如:表單格式、憑證、來源...等。

格式 Content-Type

雖然發起請求很簡單,但就像實際生活中存在各種不同的文件格式一樣,請求 API 的格式也有很多種。最常使用的兩種請求格式

  • multipart/form-data - 可攜帶文字、檔案
  • application/json - 僅允許json字串(純文字)

當然格式並不只有這兩種,可以參考 IANA - Media Types 認識所有格式。

    fetch('/example', {
      headers: {
        'Content-Type': 'application/json' // 依據自身需求調整
      }
    });

憑證 Authorization

那麼如果請求的服務需要權限或身份驗證,櫃台人員該怎麼判斷是哪位用戶?能不能操作?這些都是透過攜帶憑證 Authroization 來判斷的,但為什麼需要攜帶憑證?直接寫在請求內容不就好了嗎?沒錯!確實可以這麼做,登入通常就是這麼一回事,但每次都要求用戶填寫帳號、密碼會讓體感相當糟糕!所以系統通常會在用戶登入後配發唯一、不重複的憑證,用戶只須在執行請求時帶上就好了。可以理解為進入機構後取得了一組專屬的「服務編號」,櫃台人員可以透過編號確認用戶身份、查詢相關資料。

    fetch('/example', {
      headers: {
        Authorization: '...', // 填入專屬憑證
      },
    });

和格式一樣,憑證的類型及攜帶方式也不是只有一種,在此就不多做贅述,之後再另外寫一篇來討論 (自己挖坑)。

請求內容 Request Body

選好格式、帶上憑證後,當然不能漏了最重要的請求內容,基本上就是依據 API 文件要求的填寫內容即可。

    fetch('/example', {
      body: JSON.stringify({
        title: '標題',
        description: '簡述',
        content: '內容',
      })
    });

這裡以非常簡易的「新增文章」作為示範,一切皆須以 API 文件為準。

跨來源資源共用 CORS

所以...完成以上設置就能成功串接 API 了嗎?通常是的,但在瀏覽器上操作通常還會碰到 CORS 同源限制。CORS 相當於守衛,只有透過瀏覽器發起請求才會發生,當請求的網域與 API 網域不相同,收到回應便會被 CORS 屏蔽,只有在協定(protocol)、網域(domain)、埠號(port)完全一致時才能順利取得回應。為什麼瀏覽器要這樣限制?這是為了避免惡意網站透過 Javascript 取得用戶瀏覽器上的資料並假冒用戶發起請求,但這僅僅是保護機制的一環,並不代表有它就萬無一失了。那麼該如何解決 CORS 限制?

  1. 透過 Proxy 代理轉發請求(如 CORS anywhere)
  2. 由當前網域的後端發起請求(如 webpack-dev-server, nitro)
  3. 請後端將前端網域加入白名單(Access-Control-Allow-Origin)

前兩點基本上是一樣的東西,透過允許當前網域請求或 Access-Control-Allow-Origin:* (或明確指定前端網域,可以理解為白名單)並且存在代理機制的後端,將請求轉發至欲請求的 API。總而言之,CORS 無法單純靠前端獨立解決,需由後端調整設置。 !!! attention 注意當前端攜帶 credentials 時,Allow-Origin:* 無效,後端須明確指定前端網域,並且設定 access-control-allow-credentials: true。 !!! !!! danger 警告Proxy 代理存在一定的風險,資料可能被代理方擷取、利用,須謹慎使用! !!!

回應 Response

成功送出請求後 API 便會將請求的結果返回給我們。

狀態碼 Status Code

狀態碼能夠幫助我們快速的了解請求的結果,根據 wiki 上的描述共分為五個種類

  • 1xx - 資訊回應,表示正在處理中
  • 2xx - 成功,表示操作成功
  • 3xx - 重新導向,表示用戶需進一步操作
  • 4xx - 客戶端錯誤,表示操作失敗
  • 5xx - 伺服器錯誤,表示異常、無法處理

    詳細代碼及含意請參考 IANA - Status Code

回應內容 Response Body

但許多情境中只有狀態碼是行不通的,還需要回應內容才算是完整的流程。

行為狀態碼回應內容
GET 文章列表200文章列表
GET 單一文章200單一文章
POST 新增文章400失敗原因
DELETE 歷史文章400失敗原因

API 的回應內容結構不一定相同,一切皆須以 API 文件為準。

其他

完整範例

如果你已經完全理解了前面提到的內容,那麼聰明的你肯定不需要說明就能明白這段範例的作用了👍

    fetch('/articles', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: '...', // 填入專屬憑證
      },
      body: JSON.stringify({
        title: '標題',
        description: '簡述',
        content: '這是一篇文章',
      })
    })
    .then(response => {
      console.log('文章新增成功!可以透過 response 或瀏覽器工具查看詳細回應');
    })
    .catch(error => {
      console.log('文章新增失敗!可以透過 error 或瀏覽器工具查看詳細錯誤資訊');
    })
    .finally(() => {
      console.log('API 請求流程結束!');
    });

工具

這邊分享一些可以協助開發、除錯的請求工具,它們通常包含自動化測試、情境示例建置、生成隨機值填充內容...等強大功能。

結論

基本上 API 請求就是這麼簡單的一件事,讓我們重新把整個流程以現實生活情境描述一次。情境:用戶想要在某個單位發布文章

  1. 進入單位 - 登入及取得憑證
  2. 選擇文件類型 - 格式 Content-Type
  3. 填寫文件內容 - 請求內容 Request Body
  4. 攜帶服務編號 - 憑證 Authorization
  5. 送出表單等待回應 - 狀態碼 Status Code, 回應內容 Response Body

© 2026 · ReallifeKip · 版權所有