API 是程式之間互相溝通的方式。一個提出請求,另一個給出回應。我們以電商平台為例,看看請求由哪些部分組成、怎麼讀 JSON 回應,以及 Claude Code 串接外部資料來源時要檢查什麼。最後簡單說明 FastAPI 可能出現在哪裡。

用白話說 API 是什麼

API(Application Programming Interface)就是應用程式介面。它規定了有哪些操作可用,以及呼叫這些操作的規則。不只個別應用程式有 API,函式庫、作業系統、瀏覽器也都有。透過 API,一個程式可以請另一個程式(或其中某個部分)做某件事,並拿回結果。這裡主要談的是網路 API,也就是透過網址存取的 API。

想像一家餐廳。身為客人,您不會走進廚房,也不會教廚師怎麼做菜 - 您告訴服務生想點菜單上的什麼,服務生把點單送進廚房,再把做好的菜端給您。API 就是這位服務生。用戶端程式透過它下單,廚房(另一個程式)負責完成。您不需要知道裡面怎麼運作 - 只要看得懂菜單,知道可以點什麼、會端上什麼就夠了。

說穿了,API 就是一份契約:"可以這樣呼叫我,我會回傳這樣的結果"。

當 Claude Code 提議串接某個服務時,它得先弄清楚可以請求什麼、會拿到什麼回應。API 文件描述的就是這份"菜單"。

另外還有一支英文的搞笑短片 - "How API work"。它只是把同一個想法畫成圖,並不是主題講解。需要知道的內容,下面的文字都有。

請求和回應:以電商平台為例

想像一個電商平台,供應商從自己的程式把商品上架過去。上千個品項靠網站按鈕一個個搬很不方便,所以平台提供了 API 程式操作。例如 POST /products 新增商品,GET /reports 回傳報表。

可用操作的網址稱為 endpoint。要看懂一個請求,網址和 HTTP 方法都要看。GET /products 和 POST /products 可能做的是不同的事。GET 通常用來讀取,POST 用來把資料送去處理。

資料通常以 JSON 格式傳送。大括號把物件的欄位包在一起,字串寫在引號裡,物件清單則放在方括號裡:

{
  "name": "台燈",
  "price": 15000,
  "count": 350
}

用戶端送出請求,伺服器處理後回傳回應。下面是簡化過的交換示意,不是完整的 HTTP 封包:

POST /products
{ "name": "台燈", "price": 15000, "count": 350 }

201 Created
{ "id": 4567, "status": "added" }

201 Created 是回應的狀態,下面的 JSON 則是帶著結果的回應主體。真正的 API 會在文件裡寫明 endpoint、方法、必填參數、標頭、回應格式和可能的錯誤。比較安全的做法是先用一筆測試資料試,而不是一次送出整批資料。

API 是一份契約。Claude Code 可以寫出請求,但程式碼是否符合契約,要拿最新的文件和服務實際的回應來核對。

Frontend、backend 和兩者之間的 API

API 不只用來連接不同的應用程式。很多時候,一個應用程式內部本身就由兩個程式組成,它們之間也是透過 API 溝通。

Frontend 是您在瀏覽器裡操作的那部分應用程式。按鈕、圖片、選單、表單和頁面的行為都屬於它。它的程式邏輯通常用 JavaScript 撰寫。它可以自己做複雜的運算,也可以在需要資料或需要服務那一端執行動作時向伺服器發出請求。

Backend 是應用程式的伺服器端。它處理付款、儲存訂單、檢查存取權限、搜尋商品。開發時,伺服器可能就在您的電腦上執行;發布後則放在託管服務上。使用者不會連同頁面一起拿到它的原始碼,瀏覽器收到的只是對請求的回應。

它們怎麼溝通?一樣透過 API。Backend 提供的 endpoint 不只給外部供應商用,也給自己的 frontend 用:

  • 您打開頁面 - frontend 呼叫 /products/list,backend 回傳商品清單,frontend 把它漂亮地畫出來;
  • 您按下"購買" - frontend 把資料送到 /orders,backend 建立訂單。
  • 瀏覽器中的操作
  • frontend 發出請求
  • backend 處理
  • 帶資料的回應

所以,透過 API 溝通的可以是不同的應用程式,也可以是同一個應用程式的不同部分。在這個流程裡,瀏覽器送出請求,backend 處理資料並回傳結果。資料庫不必讓瀏覽器直接存取。

從瀏覽器發出的請求

前面說到 frontend 會"呼叫" backend 的 endpoint。來看看這在程式碼裡長什麼樣子。瀏覽器為此內建了一個函式 fetch。它向指定網址發送 HTTP 請求,並回傳回應。回應主體通常是 JSON,用 .json() 方法解析成物件。

以語系清單為例 - 也就是語言和地區設定的組合。假設 backend 已經能在 /locales 這個網址提供清單,而 frontend 要把它顯示出來。例如伺服器回傳:

[
  { "code": "en-GB", "language": "English", "country": "United Kingdom" },
  { "code": "de-DE", "language": "Deutsch", "country": "Germany" }
]

回應是怎麼來的

下面的片段在頁面處理程式的非同步函式裡執行。它負責取得資料;輸出表格的部分這裡沒有列出。

const res = await fetch("/locales");
if (!res.ok) {
  throw new Error(`HTTP ${res.status}`);
}
const locales = await res.json();
// 現在 locales 裡是表格要用的資料

讀取資料之前先檢查 res.ok。像 404 或 500 這類 HTTP 錯誤,本身並不會讓 fetch 拋出例外。網路請求沒送成功、JSON 解析失敗,則是另外的情況。這類片段丟出的錯誤應該由頁面程式碼接住,並顯示使用者看得懂的訊息。原因各不相同,但對使用者來說,結果都是拿不到資料。詳見 MDN 的 fetch 指南。

這裡有幾個小地方很容易漏看:

  • fetch 預設發送 GET - 也就是取得資料的請求。其他操作要用方法指定;例如我們的電商平台透過 POST 接收新商品;
  • /locales 是相對網址。在一般的 HTTP 頁面裡,它指向同一個 origin 的根目錄。Origin 由協定(scheme)、主機和連接埠決定;伺服器上必須有這條路由;
  • fetch 和 .json() 不會馬上拿到結果,所以前面要寫 await - "等回應回來"。

如果透過 file:// 直接把 HTML 當檔案打開,/locales 就不會指向您的 HTTP 伺服器。這個範例的頁面要透過實作了這條路由的伺服器來開啟。HTML 檔案本身不會產生這樣的路由。

Frontend 和 API 可能位於不同的 origin。這時要讓瀏覽器讀得到回應,API 伺服器必須透過 CORS 允許相應的存取。這是跨來源存取的機制,不是任何網路錯誤的統稱。把頁面和 API 放在同一個 origin 能讓範例簡單一點,但並不是所有應用程式都必須這麼做。詳見 MDN 的 CORS 說明。

誰在回應瀏覽器

誰來回應 fetch("/locales")?Backend,而且它不一定要用 Python 和 FastAPI。API 是程式之間的約定,不是某種特定的語言。同一個 endpoint 也可以用 Node.js、Go 或 Java 來寫。例如在 Node.js 伺服器的處理程式裡,可以回傳事先準備好的 locales 陣列。以下只是處理程式的片段,不是完整的伺服器:

// req 和 res 由處理程式取得,locales 已事先準備好
if (req.method === "GET" && req.url === "/locales") {
  res.statusCode = 200;
  res.setHeader("Content-Type", "application/json; charset=utf-8");
  res.end(JSON.stringify(locales));
}

從外面看,這還是同一個 HTTP 請求 GET /locales,回應裡是狀態 200 和 JSON。Frontend 不需要知道 backend 是用什麼寫的。它需要的只有網址、請求規則和回應格式。

當 Claude Code 寫出 fetch("/locales") 時,請它把另一端也拿出來看。讓代理指出是哪段程式碼在回應這個請求。接著檢查:如果回應沒有回來,使用者會看到什麼。

API 有哪些種類

API 可以按兩個特徵來分:

  • 本機和網路 - 例如函式庫的 API 是從程式碼裡直接呼叫,網路 API 則要透過網路存取。這個網路也可以是內部網路,不必連上公開的網際網路;
  • 公開和內部 - 公開 API 是給外部開發者用的,內部 API 則串起系統的各個部分。公開 API 也可能要求註冊、付費和授權。

Web API 通常使用 HTTP - 一種請求與回應的協定。REST 這個名稱您會在文件裡看到,它描述的是一種設計 API 的方式;並不是每個 HTTP API 都自動符合 REST。現階段更實用的是學會看回應裡的狀態碼:

  • 200 - 一切正常;
  • 201 - 已建立(例如 POST 之後產生的新物件);
  • 404 - 找不到;
  • 401 - 請求沒有帶上有效的身分驗證資料;
  • 429 - 請求太多;
  • 500 - 伺服器內部錯誤。

現在不必深究。重點是抓住請求和回應一來一往的基本概念。目前這樣就夠了。

狀態碼不需要死背。在 http.cat 網站上,每個 HTTP 狀態都配了一張貓咪圖。

服務為什麼需要存取金鑰

很多服務會先要您申請一把 API 金鑰 - 一段和您的帳號或專案綁在一起的字串。傳送方式依文件規定,常見的是放在請求標頭裡。服務靠它檢查存取權限,也可能用它統計您發了多少請求。在其他整合裡,您還會遇到 token 這個詞。它的用途類似,但取得方式、有效期限和權限可能不一樣。

沒有相應的存取權限,請求就不會被執行;例如伺服器可能回應 401。請求頻率超過上限,通常以 429 表示。回應的確切含義和允許的用量,要查該服務自己的文件。也有一些開放的資料來源完全不需要金鑰。

秘密金鑰能在它被授予的權限範圍內存取服務,有時花的還是您的錢。不要把它貼進對話訊息、公開的程式碼或 Git。在伺服器端,可以透過行程的環境變數傳入這個值;但變數一旦進了瀏覽器的 JavaScript,秘密就藏不住了。值要設在哪裡、怎麼傳給程式,是金鑰與環境變數的另一個主題。

去哪裡找現成的 API

透過 API,應用程式可以接入地圖、天氣、付款和物流服務。公開的文件能讓您在串接之前就先了解服務能做什麼。最好從任務本身出發:先確定需要哪些資料、多久要更新一次,以及打算拿它做什麼。

要找 API,可以看看 Postman Public API Network,這是一個收錄 API 和請求範例的目錄。找到的範例只是起點。網址、格式、存取權限和限制,還是要拿服務擁有者的官方文件核對。

FastAPI 在哪裡出現

FastAPI 是用 Python 建立 API 和 Web 伺服器的框架之一。它可以把 endpoint 和您的伺服器端程式碼連起來,接收請求並回傳 JSON 回應。只有在您要自己寫 Python backend 時才需要 FastAPI;只是使用現成的 API,就不必學它。在第 7 級,認得這個名字、分得清這條界線就夠了。

和 Claude Code 搭配時怎麼運作

有了這些概念,評估代理的工作就容易多了。它可以閱讀別人的 API 文件、撰寫用戶端請求,或用 FastAPI 建立您自己的 API。您要看清楚的是從請求到頁面上資料的具體路徑:誰送出請求、誰回應、回應又是怎麼處理的?

例如要做地震雷達,可以用 USGS 公開的 GeoJSON feed。過去一小時事件清單的網址:

GET https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson

下面是一個說明回應結構的小型教學範例,事件是虛構的,欄位也精簡過。這不是 USGS 的即時資料:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": { "mag": 4.2, "place": "教學範例地點" },
      "geometry": { "type": "Point", "coordinates": [-122.5, 38.0, 8.0] }
    }
  ]
}

features 裡放的是事件陣列。路徑 features[0].properties.mag 指向第一個事件的規模。索引 0 代表陣列的第一個元素。座標的順序是"經度、緯度、深度(公里)"。代理可以用規模決定點的大小,用座標決定點的位置。如果陣列是空的,就沒有第一個元素;如果規模是 null,代表數值未知,而不是規模為零的地震。

接下來要決定請求之後顯示什麼:

拿到什麼顯示什麼
成功回應,裡面有事件目前這一批資料。它可能和上一批完全一樣,因為不是每次請求都會有新事件。
成功回應,陣列是空的所選的時間範圍內沒有事件。舊的點可能已經落在範圍之外,不要再當成目前的事件顯示。
取得或讀取回應時出錯顯示故障訊息。如果有上一次成功取得的快照,可以保留它,並標上時間和資料可能過期的提醒。如果沒有快照,就暫時沒有東西可顯示。

請求還在進行時,頁面可以顯示載入中。要測試不同的結果,用教學用的回應很方便。這樣就不必等服務真的故障,或是等下一場地震。

現在交給 Claude Code 的任務可以這樣寫:

把指定 API 的資料接到頁面上。
先查官方文件:網址、方法、
回應格式和存取條件。列出你用了哪些欄位。
處理載入中、空清單和更新失敗的情況。
如果故障後改用舊資料,要在頁面上標示出來。
不要把秘密金鑰放進用戶端程式碼。
檢查結果,並回報實際測試了哪些狀態。

工作完成後,要看實際的請求和檢查結果,而不只是最後的畫面。另外要分清楚代理的存取權限和頁面的存取權限。MCP 可以把工具接到 Claude Code 上,但已發布的應用程式需要自己的整合。如果請求是在應用程式本身實作的,關掉代理的工作階段不應該讓網站的請求停下來。