Web API 設計の現在地 2026:現在應遵循的標準與事實標準一覽

檢視 Web API 設計時,搜尋結果前幾名常常停留在 2015~2019 年左右。這段期間,錯誤回應的標準已經出現,OAuth 的授權類型選擇基準也改變了,甚至連 API 廢止通知都已經有 RFC 了。

本文會依 Web API 設計的主要領域,整理出「到了 2026 年,現在應該遵循什麼」;並以第一手資訊(RFC、IETF 草案、大型 API 的實作)來確認。寫這篇的契機,是我讀了 2014 年的《Web API: The Good Parts》後,對書中「遵循規格;若沒有規格,就遵循事實標準」這句指引感到好奇:如今的「規格」與「事實標準」究竟到哪裡了?

整體地圖

先把「某個領域該怎麼做」與「其依據在哪裡(正式 RFC 還是沒有標準而採用事實標準)」列成一覽。細節會在各章節說明。

領域|該怎麼做|依據在哪裡
---|---|---
錯誤回應|以 Problem Details 格式回傳|RFC 9457(2023 年標準化)
日期時間格式|以 2026-08-07T12:34:56Z 形式回傳|RFC 3339(20 多年來持續有效)
方法/狀態碼|有疑問時查 RFC 9110|RFC 9110(2022 年,整合舊的 2616/7231)
認證/授權|Authorization Code + PKCE;登入用途則疊加 OIDC|RFC 9700(2025 年,BCP 240)。OAuth 2.1 草案正整合中
版本管理|基本上用路徑中的 v1。對不特定多數公開 API 可考慮日期式|無標準。Google AIP-185 與 GitHub/Stripe 的實作
廢止通知|用 Deprecation / Sunset 標頭以機器可讀方式傳達|RFC 9745(2025 年)/RFC 8594(2019 年)
分頁|採用游標方式|無標準。GitHub/Stripe 的實作是事實標準
速率限制|回傳 429 與 X-RateLimit-* 系列標頭|429 是 RFC 6585;剩餘量標頭無標準(標準化進行中)
冪等鍵|接受 Idempotency-Key 標頭|標準化停滯中。Stripe 的實作是事實標準
API 描述|用 OpenAPI 撰寫|事實標準。Linux Foundation 旗下 OpenAPI Initiative 管理規格(現行 3.2.0)

錯誤回應:RFC 9457 Problem Details

變化最大的一個領域就是這裡。過去錯誤回應的格式都是各服務自行設計:{ "error": { "code": 123, "message": "..." } } 這類形式、或錯誤陣列形式等,各種流派之所以百花齊放,單純是因為當時沒有標準;而這個狀況,已在 2023 年的 RFC 9457(最初版本為 2016 年的 RFC 7807)後告一段落。

HTTP/1.1 403 Forbidden
Content-Type: application/problem+json

{
  "type": "https://example.com/errors/insufficient-funds",
  "title": "餘額不足",
  "status": 403,
  "detail": "目前餘額為 30 點,但需要 50 點",
  "instance": "/accounts/12345/transfers/67890"
}

重點有兩個。

首先,HTTP 狀態碼與應用程式專屬的錯誤識別子,可以在同一個 body 中並存。status 放的是傳輸層的分類,type 則是「具體發生了什麼」的 URI。這兩者屬於不同層級的資訊,少了任何一個都不夠。

另一個重點是,規格正式允許擴充欄位。若像驗證錯誤那樣,需要提供欄位層級的細節,就可以額外加入自訂欄位(例如 errors 陣列)。

框架層面的支援,在不同語言生態系之間差異很大(以下為 2026 年 8 月時,依各官方文件確認)。

框架|Problem Details 支援
---|---
Spring Framework 6 / Boot 3|內建 ProblemDetail 類別。內建例外自動轉成 problem+json 需啟用 spring.mvc.problemdetails.enabled=true
ASP.NET Core|[ApiController] 的錯誤會自動轉成 ProblemDetails(預設啟用)。Minimal API 需呼叫 AddProblemDetails()(.NET 7 起)
NestJS|沒有內建支援。預設格式為 { statusCode, message }。若要對齊需自行透過例外過濾器實作
Express / Fastify / Hono|沒有內建支援。預設錯誤格式各不相同

Java 與 C# 的世界裡,這類標準已經開始進入框架;但 JS/TS 系的框架則還沒。若你用 JS/TS 撰寫 API,要不要朝 RFC 9457 對齊,以及錯誤格式要怎麼定,依然是設計者的責任。

日期時間格式:仍然是 RFC 3339

日期時間現在仍遵循 RFC 3339(2026-08-07T12:34:56Z)。以 UTC 加上 Z 回傳,顯示時交由用戶端本地化處理,這個分工在 20 多年來都沒有改變。至於 ISO 8601 與 RFC 3339 的關係,RFC 3339 可視為排除歧義後、適合實務使用的 profile;在 Web API 中應使用它。

方法/狀態碼:正典是 RFC 9110

HTTP 本身的規格已在 2022 年重新整理。長年被引用的 RFC 2616(1999 年)與其後繼的 RFC 7230 系列(2014 年),已被 RFC 9110(HTTP Semantics)、9111(Caching)與 9112(HTTP/1.1)整合取代。方法與狀態碼語義的現行正典是 9110,且其標準地位已提升為 Internet Standard。

實務上很簡單:當你對狀態碼的選擇有疑問時,就查 9110 對應章節。「400 系列是客戶端原因、500 系列是伺服器原因」的出處也在這裡。API 常見的 429 Too Many Requests 則是例外,它出自定義額外狀態碼的 RFC 6585(2012 年)。

另外,它也可用來判斷資料新舊。若說明文件引用的是 RFC 2616,就代表那篇文章至少停留在兩代以前的 HTTP 規格。

認證/授權:改變的是授權類型的選擇基準

現行標準是 OAuth 2.0(RFC 6749,2012 年)。其核心的 4 種角色與 token 概念自當時以來並未改變,但授權類型的選擇基準已大幅更新。若仍相信舊文章,最容易出問題的就是這裡。

場景|過去|2026 年
---|---|---
SPA|Implicit grant|不建議使用。改用 Authorization Code + PKCE
直接保管 ID/密碼|ROPC 仍可用|禁止使用(MUST NOT)
PKCE|行動裝置的額外防護|Public client 必須使用;其他情境也建議使用

這套選擇基準如今已經有正式 RFC 作為依據。RFC 9700〈Best Current Practice for OAuth 2.0 Security〉(2025 年 1 月,BCP 240)規定:ROPC 為 MUST NOT,Implicit 在特定條件下為 SHOULD NOT,且 public client 必須使用 PKCE(授權伺服器端也必須支援 PKCE)。常聽到的 OAuth 2.1,則是將上述內容重新整合回 OAuth 2.0 本體規格的草案,自 2020 年起持續討論,到了 2026 年 8 月仍是 rev 15,還不是 RFC。也就是說,不需要等待 OAuth 2.1 RFC 化;現在該遵循的文件早已發行。

另外,OAuth 2.0 是授權機制,不是驗證機制。若要「拿來登入」,上層還要加上 OpenID Connect。

版本管理:路徑中的 v1 與日期式兩大流派

版本管理沒有標準規格,完全屬於事實標準的世界。我們實際檢視了主要服務,確認它們目前的方式。

服務|方式|實測
---|---|---
GitHub|日期 + 標頭|x-github-api-version-selected: 2022-11-28
Stripe|日期 + 標頭|2026-07-29.dahlia
Shopify|日期放在路徑中|2026-04(按季度)
Google|把大版本號放在路徑中|AIP-185 規定必須使用 v1
Microsoft Graph|把大版本號放在路徑中|/v1.0//beta/
Azure|日期放在查詢字串中|?api-version=2023-01-01

路徑方式至今仍是數量上的多數,但面向大量不特定外部開發者的公開 API(如 GitHub、Stripe、Shopify)則更偏向日期式。最具代表性的就是 GitHub:它已從過去的 Accept: application/vnd.github.v3+json,在 2022 年轉向日期標頭方式。

v1 → v2 的一次性切換,會要求所有使用者同時大搬遷,現實上幾乎不可能發生,因此 v1 會永遠存在。日期式則是把變更切得更細,讓各個使用者依自己的節奏升級,伺服器端則透過轉換層吸收差異。是否能負擔這個成本、以及是否能掌握自己的用戶端,會決定你該選哪一種。若是內部系統或自家應用,路徑方式的缺點通常不會那麼明顯。

API 的結束方式:Deprecation 與 Sunset 標頭

關於版本管理的文章很多,但後半段「如何結束 API」卻幾乎沒人寫。其實這部分也已標準化:「這個 API 已經不建議使用」可用 Deprecation 標頭表達(RFC 9745,2025 年),「這個日期會停止」則用 Sunset 標頭表達(RFC 8594,2019 年)。

Deprecation: @1735689600
Sunset: Sun, 01 Aug 2027 00:00:00 GMT
Link: <https://example.com/docs/migration>; rel="deprecation"

Deprecation 表示「從何時起被標示為非推奨」,以 Unix 時間戳表示;Sunset 則表示「何時停止」,以 HTTP 日期格式表示。也可以透過 Link 標頭提供遷移文件。

若只靠部落格與電子郵件公告廢止,實際呼叫 API 的程式碼根本不一定會收到。只要把資訊放進回應標頭,客戶端的日誌與監控就會直接留下紀錄。這兩個標頭的價值,在於通知對象從「開發者的信箱」轉為「客戶端的執行日誌」。若你手上已經有準備廢止的端點,下一次廢止通知就可以直接用上。

分頁:游標方式已成主流

分頁也沒有標準規格,但事實標準的答案已經很明確:若是大量資料或無限捲動,應選游標方式(以絕對位置為基準)。

傳統的 offset 方式(?page=3?offset=100&limit=20)有兩個問題。第一,越後面的頁面越慢。OFFSET 100000 代表資料庫得先實際讀出 10 萬筆再丟棄,因此頁數越深,成本就越線性地上升。第二,資料會錯位。當你看第 1 頁時若插入一筆新資料,整體就會往後偏移一格,導致第 2 頁重複看到同一筆資料,或反過來漏讀。

游標方式則是以「最後看過的 ID」為基準,用 WHERE id < :cursor ORDER BY id DESC LIMIT 20 取得資料,如此一來可以透過索引直接跳到該位置,不論第幾頁都能維持固定速度,途中有插入/刪除也不會錯位。代價是無法直接跳到「第 5 頁」;因此若是需要頁碼跳轉的後台介面,offset 方式仍然有其用處。

下一頁的傳遞方式,可參考 GitHub 的 Link 標頭。

Link: <https://api.github.com/repositories?since=369>; rel="next"

分頁方式本身沒有標準,但這種傳遞方式的元件有標準:Link 標頭與 rel="next" 定義於 RFC 8288(Web Linking)。曾經很熱門的 HATEOAS(在回應中包含下一步操作的連結)雖然沒有全面普及,但以 rel="next" 的形式部分保留下來了。

另外要注意的是,分頁方式屬於 API 的外部規格,一旦日後更改,就會需要所有用戶端一起修改。因此這是應該在最初就決定好的領域。

速率限制與冪等鍵:標準化正在追趕實作的領域

這兩者的狀況很有意思:實際運作的事實標準先穩定下來,而標準化則是後來追上。

速率限制目前確定的內容,是超額時回傳 429 Too Many Requests(RFC 6585,2012 年),以及用 Retry-After 告知何時恢復。至於剩餘量的標頭,並沒有標準;X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset 這類帶 X- 前綴的形式,已成為各家事實標準。

IETF 的 httpapi 工作小組正在推進這部分的標準化(截至 2026 年 8 月,草案為 rev 11/Active)。但有趣的是,草案並不是直接把現有的 X- 三標頭形式標準化。原因在於,X- 前綴這個慣例本身就已在 RFC 6648(2012 年)中被不建議新採用,因此無法直接把既有事實標準原封不動地標準化。

草案定義的是 RateLimit-Policy(限制規則)與 RateLimit(目前剩餘量)兩個標頭,並使用 Structured Fields,格式如下:

RateLimit-Policy: "default";q=100;w=10
RateLimit: "default";r=50;t=30

q 是配額,w 是時間窗(秒),r 是剩餘量。t 是 effective window,表示「未來 t 秒內不能超過 r 的使用量」。這不是像 X-RateLimit-Reset 那樣的「距離重置還剩幾秒」;也不保證 t 秒後就會完全恢復配額(規格明確寫明,數值可能在下一個回應中改變)。換句話說,即使標準化完成,也不會只是把 X-RateLimit-* 改個名稱而已。若現在就要實作,現實作法仍是先配合 X-RateLimit-* 的事實標準,並等待草案完成後再決定是否切換。

冪等鍵的情況更極端:Idempotency-Key 標頭的標準化草案 rev 07 已於 2026 年 4 月到期(Expired),標準化流程本身也停住了。即便如此,冪等鍵仍是支付類 API 的必要機制,而 Stripe 的文件至今仍被視為事實上的規格書。

簡要整理 Stripe 規格的要點:只適用於 POST;key 必須是足夠隨機的字串(例如 v4 UUID,最長 255 字元);相同 key 的重送會直接回傳第一次請求的結果(包括狀態碼與 body),不論成功或失敗;若用同一個 key 搭配不同參數,則會報錯。key 可能在 24 小時後被刪除,刪除後再次使用會被視為新請求。也就是說,它不是永久性去重,而是為了安全重試而設計的短期機制。各家的實作大致也都遵循這個模式。

在標準化跟不上的領域裡,做得好的實作本身就會變成規格書。這兩者就是典型例子;即使找不到 RFC,也不要放棄,值得直接去找事實標準的原始實作(大型 API 的參考文件)。

API 描述:OpenAPI 3.2.0

API 規格描述格式的事實標準是 OpenAPI,目前最新版本是 3.2.0(2025 年 9 月)。如果你還是習慣用「Swagger」這個名字,代表你可能還停在 2.0 的世界,建議連名稱一起更新(Swagger 2.0 後來被捐給 OpenAPI Initiative,並演變為 OpenAPI)。

之所以能稱得上事實標準,也有可驗證的依據。管理規格的 OpenAPI Initiative,是 Linux Foundation 底下中立於各廠商的組織,Google、Microsoft、IBM、Bloomberg、SAP、Salesforce 等都參與其中。實作層面,GitHub 與 Stripe 都在各自的儲存庫中公開官方 OpenAPI 描述。框架層面,FastAPI 直接把 OpenAPI 產生整合為設計核心,而 ASP.NET Core 在 .NET 9 之後也把生成能力納入模板預設(Java 世界則以 springdoc-openapi 這個社群函式庫最常見)。雖然找不到能精確證明採用率的獨立調查,所以無法給出百分比,但沒有其他格式能像它一樣,同時在「建置端」與「發佈端」如此成為基礎設施。

它的定位也改變了。過去的 Swagger 比較像是「把 API 文件漂亮地顯示出來」;現在的 OpenAPI 則更像是從 schema 出發,產生型別化 client 與 server stub 的起點,而文件只是副產品。

至於回應資料格式本身,現在的狀況也值得一提:公開 Web API 多半已固定使用 JSON。過去常見的「用 Accept 標頭在 JSON 與 XML 間切換」這種設計,因為想把規格維持簡單而逐漸式微。格式多樣性的需求則移到別處:內部服務間通訊多用 gRPC / Protocol Buffers;若希望由 client 主導選擇欄位,則使用 GraphQL,應用場景已分化。

沒有標準的領域要怎麼查

如前所述,若某領域已有 RFC,就直接照 RFC 做即可。真正麻煩的是版本管理、分頁這些沒有標準的領域,而這些地方該參照什麼,我們也一併確認了。

企業級 API 設計指南中,最具體系性的可看 Google AIP(API Improvement Proposals)。它是有編號的規則集,例如版本管理中 v1 必須使用(AIP-185)就能直接查到。若想看得更像說明文章,Zalando RESTful API Guidelines 很適合,內容對「為什麼要這樣做」寫得很詳細。老牌的 Google JSON Style Guide 也依然活著;從儲存庫可見它在 2025 年已從內部版本同步更新,並不是被放著不管的文件。

至於新的標準動態觀測點,則是 IETF 的 httpapi 工作小組;像速率限制與冪等鍵這類 Web API 周邊標準化,都集中在這裡。

總結來說,查詢順序應該是這樣:先看有沒有 RFC(RFC Editor);沒有的話,看是否正在標準化(IETF Datatracker);再沒有,就去看事實標準的實作原型(例如 Google AIP 或 GitHub / Stripe 這類大型 API 的實作)。本文各領域,就是依照這個流程在 2026 年 8 月時完整走過一遍後整理而成。

webapi-standards-flow-2026.png

參考連結

以下是我確認過的第一手資訊清單(皆已於 2026 年 7~8 月確認可 पहुँच)。

RFC

制定中的草案

設計指南與事實標準實作

株式会社シンシア

株式会社xincere正在招募沒有實務經驗的工程師與學生工程實習生,並與他們一同工作。
※ 關於在シンシア的工作方式,請見此處

在シンシア,每年約有 100 位沒有實務經驗的人提出申請並接受技術面試。
透過這些經驗,我們在此介紹「希望沒有實務經驗的人也務必要培養起來的技術能力」。


原文出處:https://qiita.com/tatsuya582/items/a800739c02eadff68c70


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝7   💬4   ❤️3
221
🥈
我愛JS
📝1   💬2   ❤️1
51
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登