API(Application Programming Interface,應用程式介面)是程式使用另一個程式元件能力的介面。 理解一個 API,不只要知道「怎麼呼叫」,還要知道「在什麼條件下,可以期待什麼結果」。 這篇從提供者與使用者的關係出發,說明介面、實作與行為契約如何分工。 不需要先熟悉特定語言、框架或網路協定。
查證日期:2026-11-02。官方實例採 Python 3.14 與 Java SE 25 文件;本文只查閱文件。 自創例子使用文字與偽碼,未實際執行,不代表任何既有產品或標準的規定。
誰提供能力,誰使用能力
提供者(provider)負責實現一項能力,並說明外部程式可以如何使用。 使用者(consumer/caller)是呼叫這項能力的程式;撰寫呼叫端的開發者需要理解使用規則。 這裡的「使用者」不一定是操作畫面的人,「提供者」也不一定是遠端伺服器。
例如 Python/C API 讓 C 或 C++ 程式使用 Python 直譯器的能力, 可用來撰寫擴充模組,也可把 Python 嵌入其他應用程式。 這個例子沒有要求以 HTTP 傳送請求,因此 API 不能直接等同網址或 JSON。 參考 Python 3.14:C API 導論。
提供者與使用者是相對於某個介面而言的角色。 一個元件可以對外提供資料讀取能力,同時呼叫另一個元件取得資料;它在兩個邊界扮演不同角色。
公開介面與內部實作
可以把兩者分成兩個問題:
| 面向 | 回答的問題 | 讀取清單項目的例子 |
|---|---|---|
| 對外介面 | 使用者能做什麼、如何提出操作、能期待什麼 | 提供清單與位置,取得該位置的項目 |
| 內部實作 | 提供者如何完成這項能力 | 使用陣列、鏈結結構,或其他儲存方式 |
使用者應根據介面承諾編寫程式,而不是把某次觀察到的內部做法當成保證。
但哪些內容屬於承諾,仍要看提供者公布的文件與支援政策;
語言中的 public、能匯入的名稱或能呼叫的方法,本身不足以證明它是穩定支援的 API。
Python 的文件便區分不同穩定程度:PyUnstable 開頭的 API 可能在次版本改變,
底線開頭的私有 API 甚至可能在修補版本無預告改變。
「找得到入口」與「可以依賴哪些保證」是兩件事。
參考 Python 3.14:C API 穩定性。
內部做法也可能影響使用成本。Java 的 List 文件指出,不同實作的索引存取成本可能不同。
因此不能只從相同的方法名稱,推定它們具備相同的效能保證。
參考 Java SE 25:List 說明。
契約不只有名稱與型別
API 的契約(contract)描述使用者可以依賴的規則與提供者承諾的行為。 操作名稱、參數與結果型別能交代呼叫形式,卻不一定能完整交代結果的意義。
例如只寫「輸入位置,輸出項目」,仍不知道位置從 0 還是 1 開始, 超出範圍時會發生什麼,以及讀取是否會改變原清單。 這些問題直接影響呼叫端能否正確使用介面。
真實例子是 Java 的 List.get(int index):文件除了方法宣告,還說明它會回傳指定位置的項目,
並規定 index < 0 或 index >= size() 時拋出 IndexOutOfBoundsException。
這些行為不能只靠參數是整數、回傳值是元素型別得知。
參考 Java SE 25:List.get。
用一個假想介面看雙方責任
以下是本文自訂的教學契約,與 Java、Python 的實際規則無關。 假設有個操作叫做「讀取項目」:
讀取項目(items, index) → 成功(項目) 或 失敗(位置超出範圍)
這個寫法只是偽碼;成功、失敗 是結果的概念標記,不指定語言、例外機制或訊息格式。
| 契約項目 | 本例約定 |
|---|---|
| 能力 | 讀取有順序清單中的一個項目 |
| 輸入 | items 是有限的有順序清單;index 是整數 |
| 位置規則 | 第一個位置是 0;清單長度為 n 時,有效位置是 0 ≤ index < n |
| 有效位置的結果 | 回傳 成功(items 原本在 index 的項目) |
| 無效位置的結果 | 若清單與整數輸入成立,但位置無效,回傳 失敗(位置超出範圍) |
| 狀態影響 | 上述成功或失敗都不改變原清單的內容與順序 |
為了聚焦,本例不討論其他程式同時修改清單的情況;若提供者要支援那種使用情境,須另說明規則。 本例也沒有約定非清單、非整數等輸入的處理方式,不能自行補上保證。
前置條件與後置條件
前置條件(precondition)是操作開始時需要成立的條件; 後置條件(postcondition)是操作結束時必須成立的條件。 Microsoft 的 Code Contracts 文件也區分正常結束與特定例外結束時的後置條件。 此處借用概念,不要求使用其工具;該文件的工具適用範圍是 .NET Framework。 參考 Microsoft:Code Contracts。
對本例的成功路徑,可以這樣讀:
呼叫前:items 是清單,index 是整數,而且 0 ≤ index < 清單長度
呼叫後:結果是成功,值等於呼叫前指定位置的項目,原清單不變
使用者負責滿足取得成功結果所需的前提;提供者負責在這些前提成立時履行承諾。 本例還額外約定了「清單與整數成立,但位置無效」的失敗路徑: 使用者不能期待成功,提供者仍須回傳約定的失敗結果並保持清單不變。
不符合成功前提,不等於介面一定要拋出例外,也不等於提供者可以忽略已寫明的失敗保證。 要看實際契約對該情況承諾了什麼;如果文件沒有保證,就不能推定會安全失敗或自動修正。 前面的 Java 實例明定拋出例外,本例則明定回傳失敗結果,兩者各有自己的規則。
對照三種情況
以下每一列都獨立從 items = [「甲」, 「乙」] 開始:
| 情況 | 呼叫與觀察 | 如何判讀 |
|---|---|---|
| 正常使用 | 位置 1,得到 成功(「乙」),清單不變 | 符合前提,也符合結果承諾 |
| 不符合成功前提 | 位置 2,得到 失敗(位置超出範圍),清單不變 | 無法取得項目,但提供者遵守了明訂的失敗規則 |
| 提供者違約 | 位置 1,得到 成功(「甲」) | 使用者符合前提,提供者卻回傳錯誤位置的項目 |
若位置 1 回傳「乙」,卻同時刪除原清單中的「乙」,也違反本例的契約。 結果值正確並不足夠,還要符合「原清單不變」這項可觀察的承諾。
閱讀一個 API 時,先確認哪些事
可以先找出它提供的能力、可依賴的入口、成功所需條件,以及結果與狀態變化的保證。 接著查看不符合條件時的規定,區分文件明訂的行為與自己推測的行為。 如果關鍵條件沒有說清楚,問題可能在契約資訊不足,不能只靠猜測實作補齊。
本篇先建立這個閱讀方式。資料限制與錯誤的表達方式,見輸入、輸出與失敗語意; 契約演進見相容性與演進,驗證承諾的方法見 API 測試。
相關文件
- API 共通知識索引:查看閱讀順序、內容範圍與後續規劃。