iT邦幫忙

2025 iThome 鐵人賽

DAY 11
0

透過呼叫 API 來實戰演練 1

API Client 套件

在 Elixir 裡面有非常的的 API Client 套件可以選擇,還好最近大家比較統一的使用一個叫 Req 的套件。
用起來很直覺卻也很有彈性,近幾年大多套件與範例也都轉用 Req,這邊就用 Req 來做教學。

在專案中安裝 Req 套件

通常在 Elixir 裡安裝套件時,搜尋的途徑可能是

  1. Elixir 的 package 網站 https://hex.pm/ 搜尋套件名稱,再點進去套件頁面右邊有設定與目前的版本可以複製。
    https://ithelp.ithome.com.tw/upload/images/20250925/20141054534MTOWYWX.png
  2. 找到該套件的 Github 頁面,如這次的 req https://github.com/wojtekmach/req ,底下的 Readme 也通常會有安裝方法

我們從以上其中一個地方拿到

{:req, "~> 0.5.15"}

貼進 mix.exs 檔案裡的 deps 函式中

defp deps do
  [
    {:req, "~> 0.5.15"}
  ]
end

存檔後在終端機執行 mix deps.get 取得

呼叫 API

我們先在 lib 資料夾建立一個全新的 countries.ex 檔案

lib/countries.ex:

defmodule Countries do
  def list_all do
  end
end

定義 Countries 模組與裡面的 list_all 函式,
接下來我們準備要從 REST Countries 這個開放 API 來抓全部的國家資料

目前一次啦全部的資料需要指定回覆欄位,我們這次使用 name, languages, population

我們要呼叫的端點為 GET https://restcountries.com/v3.1/all?fields=name,languages,population

雖然 query 可以塞進網址內,但是為了好操作 Req 提供 params 選項讓我們填 map

def list_all do
  Req.get("https://restcountries.com/v3.1/all",
    params: %{fields: "name,languages,population"}
  )
end

使用 iex -S mix 進到互動介面
並呼叫 Countries.list_all
我們會得到

{:ok,
 %Req.Response{
   status: 200,
   headers: %{
     "cache-control" => ["public, immutable, max-age=31556926"],
     "connection" => ["keep-alive"],
     "content-type" => ["application/json"],
     "date" => ["Thu, 25 Sep 2025 14:36:03 GMT"],
     "server" => ["nginx/1.22.1"]
   },
   body: [
     %{
       "languages" => %{"eng" => "English", "jam" => "Jamaican Patois"},
       "name" => %{
         "common" => "Jamaica",
         "nativeName" => %{
           "eng" => %{"common" => "Jamaica", "official" => "Jamaica"},
           "jam" => %{"common" => "Jamaica", "official" => "Jamaica"}
         },
         "official" => "Jamaica"
       },
       "population" => 2961161
     },
     ...後略

Req 呼叫完 API 回給我們一個有 :ok 的 tuple
這個時候我們可以選擇接住這個結果的方式,常見的法可以是:

case Req.get("https://restcountries.com/v3.1/all",
        params: %{fields: "name,languages,population"}
      ) do
  {:ok, response} ->
    # 處理成功的程式
    response

  {:error, error} ->
    # 處理錯誤的程式
    error
end

但我們這次先假裝我們不需要處理錯誤情形的情況,用一樣的形狀進行 pattern maching 把 response 接下來

{:ok, response} =
  Req.get("https://restcountries.com/v3.1/all",
    params: %{fields: "name,languages,population"}
  )

接下來我們可以使用 response.body 取出資料,Req 已經幫我們把回應的 json 字串轉成 list 了

defmodule Countries do
  def list_all do
    {:ok, response} =
      Req.get("https://restcountries.com/v3.1/all",
        params: %{fields: "name,languages,population"}
      )

    response.body
  end
end

備註:如果改了程式碼想要在 iex -S mix 使用新的版本的函式的話可以執行 recompile 來重新編譯新的程式碼

我們就得到這個超長的 list 裡面有很多有國家資料的 map

  %{
    "languages" => %{"eng" => "English"},
    "name" => %{
      "common" => "Trinidad and Tobago",
      "nativeName" => %{
        "eng" => %{
          "common" => "Trinidad and Tobago",
          "official" => "Republic of Trinidad and Tobago"
        }
      },
      "official" => "Republic of Trinidad and Tobago"
    },
    "population" => 1399491
  },
  %{
    "languages" => %{"hye" => "Armenian"},
    "name" => %{
      "common" => "Armenia",
      "nativeName" => %{
        "hye" => %{
          "common" => "Հայաստան",
          "official" => "Հայաստանի Հանրապետություն"
        }
      },
      "official" => "Republic of Armenia"
    },
    "population" => 2963234
  },

上一篇
單元測試
下一篇
透過呼叫 API 來實戰演練 2
系列文
通勤看手機就可讀懂的 Elixir 語言入門教學12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言