跳至主要內容
Aurikle
AI與系統Aurikle

客製軟體接口契約怎麼寫

兩套系統交換資料之前,接口契約寫明路徑或訊息種類、必填欄、身份驗證、錯誤碼、版本,以及不相容的改動要誰點頭。需求規格寫的是做完之後業務上什麼算達成;驗收和使用者驗收寫的是畫面上怎樣把那一條做出來;這一頁寫的是兩邊系統互相呼叫時,欄位和錯誤怎樣對得上。

目錄
  1. 接口契約和需求規格、驗收分開寫
  2. 路徑或訊息種類先有名字
  3. 必填欄寫在結構裡
  4. 身份驗證寫明用哪一種
  5. 錯誤寫回應碼和這一次的意思
  6. 文件版本和接口版本分開
  7. 不相容的改動要先有人點頭
  8. 名稱、必填欄、驗證、錯誤和版本寫上,才算這份契約
對應服務客製軟件、網站與應用程式閱讀這篇

接口契約和需求規格、驗收分開寫

需求規格回答的是哪一個角色在哪一個畫面完成哪一件事、誰對那一條負責、這一版明確不做什麼。驗收標準回答的是示範時旁人看得到什麼。使用者驗收回答的是那一條的負責人是否自己做過,或在場看完。接口契約回答的是另一件事:這一邊送出的一筆,另一邊按哪一條路徑或哪一種訊息收下,缺了哪一欄就算沒送到,身份驗證不過或處理失敗時回哪一個碼。四份可以指到同一次交換的名稱。規格裡的達成狀態不改寫成路徑,驗收清單也不把錯誤碼當成畫面上的一句文案來勾。分別見 客製軟體需求規格怎麼寫、客製軟體驗收標準怎麼寫、客製軟體 UAT 怎麼做。

範圍變更管的是規格要不要改、誰可以收下修改。見 客製軟體範圍變更怎麼管。交付仍走 客製軟件、網站與應用程式。另一邊若是現場設備而不是另一套業務畫面,欄位仍寫在這份契約,設備怎樣接到既有系統另見 設備怎麼接到既有業務系統。契約封面寫自己的版本、兩邊系統的名稱,以及存放路徑。

路徑或訊息種類先有名字

2026年10月28日閱讀的 OpenAPI Specification 3.1.2 頁首寫明版本日期為 2025年9月19日。該頁寫明,OpenAPI Specification 定義一套與程式語言無關的接口描述,用來說明 HTTP API,讓人和電腦不必讀原始碼、不必另找文件、也不必查看網絡流量,就能了解服務能做什麼。該頁並寫明,一份 OpenAPI Description 至少要有 paths、components 或 webhooks 其中之一。Paths Object 放的是各個端點的相對路徑及其操作;路徑接到 Server Object 的 URL 後面,組成完整網址。路徑欄位的名稱必須以斜線開頭。

同一頁寫明,Operation Object 描述路徑上的單次操作,可以包含參數、請求本體、回應,以及該次操作使用的身份驗證。交換若不是由呼叫方發起的 HTTP,該頁的 webhooks 用一個不重複的鍵名指到每一則 webhook,並用 Path Item 描述由 API 提供方發起的請求和預期回應。隊列或檔案交換若對不上這兩種寫法,契約仍為每一種訊息寫一個不重複的名稱,並在封面註明它不是該頁的 path 或 webhook。沒有名稱的交換不進契約。該頁的寵物店例子只說明格式,不拿來當專案的路徑。

必填欄寫在結構裡

同一份 OpenAPI 3.1.2 寫明,Schema Object 是 JSON Schema Draft 2020-12 的超集;除非另有說明,關鍵字的定義沿用 JSON Schema。2026年10月28日閱讀的 JSON Schema Validation 是 Internet-Draft draft-bhutton-json-schema-validation-01,頁首寫明發表於 2022年6月16日、於 2022年12月18日到期、預期狀態為 Informational,作者為 A. Wright、H. Andrews、B. Hutton。該草案對 required 的寫法是:它的值必須是陣列,元素必須是字串且不得重複;一個物件要算通過,陣列裡的每一項都必須是該物件的屬性名稱;省略這個關鍵字,效果與空陣列相同。

契約裡的請求或回應若有必填欄,就把欄名放進該結構的 required。欄名沒有寫進這一陣列,依該草案就不算必填,接收方不能事後把空值說成對方漏送。公司自己的必填名單寫在契約上並註明日期;草案沒有替專案列出欄名。參數若在路徑上,OpenAPI 寫明該參數的 required 必須為 true。選填欄可以出現在結構裡,但不放進 required。金額、單號、狀態這一類名字,以兩邊已經在用的欄名為準,不在契約裡另起一個只給文件看的別名。

身份驗證寫明用哪一種

OpenAPI 3.1.2 的 Security Scheme Object 寫明可用的方案包括 HTTP 驗證、API 金鑰(放在標頭、cookie 或查詢參數)、相互 TLS、OAuth 2.0 在 RFC 6749 裡的幾種常見流程,以及 OpenID Connect。type 的有效值為 apiKey、http、mutualTLS、oauth2、openIdConnect。該頁並寫明,以 2020 年而言,implicit 流程即將被 OAuth 2.0 Security Best Current Practice 標為不建議;多數情況建議使用帶 PKCE 的授權碼流程。這是該頁對方案的列舉和建議,不是要求這次交換必須採購某一種產品。

契約選一種寫進 security,並寫明鍵名落在標頭、cookie 還是查詢參數。整份 API 的 security 可以被單次操作覆寫;該頁寫明,空陣列表示拿掉上層的驗證宣告。沒有寫 security、也沒有寫明這次交換故意不驗證,接收方不依口頭約定放行。憑證何時更換寫在公司自己的維運紀錄,契約只寫方案種類和鍵名。密碼、權杖和私鑰不貼進契約正文。

錯誤寫回應碼和這一次的意思

同一份規範的 Responses Object 把 HTTP 回應碼對到預期回應。該頁寫明,文件不必涵蓋所有可能的回應碼,因為事先未必知道;但仍預期寫出成功時的回應,以及已知的錯誤。Responses Object 必須至少有一個回應碼;若只寫一個,應該是成功呼叫的回應。回應碼應從 IANA Status Code Registry 裡已登記的碼挑選。default 可以用來說明未被逐碼寫出的回應。

契約為這一次交換寫下成功時的碼,以及已知錯誤的碼。每一個碼配一段說明,寫這一次失敗時對方看得到什麼,而不是只重複該碼的通用名稱。尚未遇過的錯誤不預先編一個專案專用的數字;未列出的碼走 default,說明寫「契約未列」。登記冊沒有的自訂碼不寫進這一欄。成功和已知錯誤都還沒寫,這一條操作不算寫完。

文件版本和接口版本分開

OpenAPI 的 info.version 是必填。該頁寫明,它是 OpenAPI Document 的版本,並與規範本身的版本、所描述 API 的版本,以及 OpenAPI Description 的版本都不是同一件事。openapi 欄位則是這份文件使用的規範版本,該頁寫明它和 info.version 無關。契約封面若只填了 info.version,旁邊要註明它是文件版本還是接口版本;兩個都要時分成兩欄。

2026年10月28日閱讀的 Semantic Versioning 2.0.0 該頁沒有刊登日期,作者為 Tom Preston-Werner。摘要寫明,版本號 MAJOR.MINOR.PATCH 之中,做了不相容的 API 改動就遞增 MAJOR,以向後相容的方式增加功能就遞增 MINOR,向後相容的錯誤修正就遞增 PATCH。規範第 1 條寫明,使用這套版本的軟體必須宣告一份公開 API。第 8 條寫明,只要公開 API 出現向後不相容的改動,MAJOR 就必須遞增。公司若採用這套編號,在契約封面寫明,並把公開 API 指到這一份契約,而不是指到尚未寫完的會議紀錄。

不相容的改動要先有人點頭

SemVer 第 3 條寫明,某個版本一旦發布,該版本的內容不得再改;任何修改都必須作為新版本發布。第 8 條把向後不相容的改動放在 MAJOR。該頁關於停用的問答寫明,停用公開 API 的一部分時應做兩件事:更新文件讓使用方知道,並發行一個帶著這項停用的 MINOR;在下一個 MAJOR 完全移除之前,至少要有一個包含停用的 MINOR,使用方才有辦法轉過去。OpenAPI 把操作的 deprecated 設為 true 時,該頁寫明使用方應該停止使用該操作,預設值是 false。

誰可以點頭讓不相容的改動進入下一版,寫在契約封面,註明姓名和同意日期。SemVer 沒有指定這個人。沒有這一行,路徑、必填欄或錯誤碼的不相容改動不發布給另一邊。文件可以先改,呼叫仍停在上一版,直到這個人簽過。範圍變更那一篇管的是業務規格,不代替這一行簽名。公司若採用 SemVer,簽名之後 MAJOR 才遞增,舊版依第 3 條不再被原地改寫。未採用 SemVer 的,仍要換上一條與舊版不同的接口版本字串,並在封面寫明編號辦法。

名稱、必填欄、驗證、錯誤和版本寫上,才算這份契約

路徑或訊息種類沒有名稱、必填欄沒有放進 required 或沒有註明這一筆沒有必填、身份驗證方案空白、成功回應碼還沒有、接口版本還沒有和文件版本分開,這一條都不進雙方可以呼叫的清單。口頭說先對著測試環境打,不補上這些欄。

用三件事看這份契約能不能給另一邊用:每一條交換都有路徑或訊息名稱、必填欄和已知錯誤碼寫在同一條、不相容的改動有負責人和同意日期。有一項空著,這一條留在草稿,另一邊不按它上線。

相關筆記