日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Microsoft REST API指南

發布時間:2023/12/4 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Microsoft REST API指南 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????經過3個月的碎片時間的翻譯和校驗,由長沙.NET技術社區翻譯的英文原文文檔《Microsoft REST API指南?》已經翻譯完成,現刊載前十一章如下,歡迎大家點擊“查看原文”按鈕,查看指南的完整內容。

????PS:內容很長,全文讀完大概需要耗時100分鐘。

Microsoft REST API指南工作組

NameNameName
Dave Campbell (CTO C+E)Rick Rashid (CTO ASG)John Shewchuk (Technical Fellow, TED HQ)
Mark Russinovich (CTO Azure)Steve Lucco (Technical Fellow, DevDiv)Murali Krishnaprasad (Azure App Plat)
Rob Howard (ASG)Peter Torr (OSG)Chris Mullins (ASG)

Document editors: John Gossman (C+E), Chris Mullins (ASG), Gareth Jones (ASG), Rob Dolin (C+E), Mark Stafford (C+E)


感謝.NET長沙社區提供的翻譯,感謝譯者李文強,譯者周尹?
本文首發 .NET社區公眾號,歡迎關注, 搜索 MoreDotNetCore ,里面有最新的原創性資訊,獲得第一手的資料。

Microsoft REST API指南

摘要

Microsoft REST API指南作為一種設計原則,鼓勵應用程序開發人員通過RESTful HTTP接口訪問資源。

文檔原則認為REST API應該遵循一致的設計指導原則,能為開發人員提供最流暢的體驗,令使用它們變得簡單和直觀。

本文檔建立了Microsoft REST API應該遵循的指導原則,以便統一一致的開發RESTful接口。

2. 目錄

  • Microsoft REST API Guidelines Working Group

  • 1. 摘要

  • 2. 目錄

  • 3. 介紹

    • 3.1. 推薦閱讀

  • 4. 解讀指導

    • 4.1. 應用指導

    • 4.2. 現有服務指南和服務版本化

    • 4.3. 要求的語言

    • 4.4. 許可證

  • 5. 分類

    • 5.1. 錯誤

    • 5.2. 故障

    • 5.3. 潛在因素

    • 5.4. 完成時間

    • 5.5. 長期運行的API故障

  • 6. 客戶端指導

    • 6.1. 忽略規則

    • 6.2. 變量排序規則

    • 6.3. 無聲失效規則

  • 7. 一致性基礎

    • 7.10.1. Clients-specified response format

    • 7.10.2. Error condition responses

    • 7.4.1. POST

    • 7.4.2. PATCH

    • 7.4.3. Creating resources via PATCH (UPSERT semantics)

    • 7.4.4. Options and link headers

    • 7.1. 網址結構

    • 7.2. 網址長度

    • 7.3. 標準標識符

    • 7.4. 支持方法

    • 7.5. 標準請求請求頭

    • 7.6. 響應請求頭

    • 7.7. 自定義請求頭

    • 7.8. 指定頭部為查詢參數

    • 7.9. PII 參數

    • 7.10. 響應格式

    • 7.11. HTTP狀態碼

    • 7.12. 可選的客戶端庫

  • 8. CORS 跨域

    • 8.1.1. 預檢

    • 8.1. 客戶端指導

    • 8.2. 服務端指導

  • 9. 集合

    • 9.8.1. Server-driven paging

    • 9.8.2. Client-driven paging

    • 9.8.3. Additional considerations

    • 9.7.1. Filter operations

    • 9.7.2. Operator examples

    • 9.7.3. Operator precedence

    • 9.6.1. Interpreting a sorting expression

    • 9.3.1. Nested collections and properties

    • 9.1. 項的key

    • 9.2. 序列化

    • 9.3. 集合URL模式

    • 9.4. 大集合

    • 9.5. 修改集合

    • 9.6. 集合排序

    • 9.7. 過濾

    • 9.8. 分頁

    • 9.9. 復合集合操作

  • 10. 增量查詢

    • 10.1. 增量鏈接

    • 10.2. 實體表示

    • 10.3. 獲得增量鏈接

    • 10.4. 增量鏈接響應內容

    • 10.5. 使用增量鏈接

  • 11. JSON標準化

    • 11.3.1. The?DateLiteral?format

    • 11.3.2. Commentary on date formatting

    • 11.2.1. Producing dates

    • 11.2.2. Consuming dates

    • 11.2.3. Compatibility

    • 11.1. 主要類型的JSON格式化標準化

    • 11.2. 日期和時間指南

    • 11.3. 日期和時間的JSON序列化

    • 11.4. 持續時間

    • 11.5. 間隔

    • 11.6. 重復間隔

  • 12. 版本

    • 12.1.1. Group versioning

    • 12.1. 版本格式

    • 12.2. 版本的時間

    • 12.3. 非延續性更改的定義

  • 13. 長時間運行的操作

    • 13.2.1. PUT

    • 13.2.2. POST

    • 13.2.3. POST, hybrid model

    • 13.2.4. Operations resource

    • 13.2.5. Operation resource

    • 13.2.6. Operation tombstones

    • 13.2.7. The typical flow, polling

    • 13.2.8. The typical flow, push notifications

    • 13.2.9. Retry-After

    • 13.1. 基于資源的長時間運行(RELO)

    • 13.2. 分步運行的長時間操作

    • 13.3. 操作結果保留策略

  • 14. Throttling, Quotas, and Limits

    • 14.4.1. Responsiveness

    • 14.4.2. Rate Limits and Quotas

    • 14.4.3. Overloaded services

    • 14.4.4. Example Response

    • 14.1. Principles

    • 14.2. Return Codes (429 vs 503)

    • 14.3. Retry-After and RateLimit Headers

    • 14.4. Service Guidance

    • 14.5. Caller Guidance

    • 14.6. Handling callers that ignore Retry-After headers

  • 15. 通過webhooks推送通知

    • 15.7.1. Creating subscriptions

    • 15.7.2. Updating subscriptions

    • 15.7.3. Deleting subscriptions

    • 15.7.4. Enumerating subscriptions

    • 15.6.1. Notification payload

    • 15.1. 范圍

    • 15.2. 原則

    • 15.3. 訂閱類型

    • 15.4. 調用序列

    • 15.5. 驗證訂閱

    • 15.6. 接收通知

    • 15.7. programmatically訂閱管理

    • 15.8. 安全性

  • 16. 不支持的請求

    • 16.2.1. Error response

    • 16.1. 基本指導

    • 16.2. 特征允許列表

  • 17. 命名準則

    • 17.1. 途徑

    • 17.2. 框架

    • 17.3. 避免的命名

    • 17.4. 規范的復合詞

    • 17.5. 標識屬性

    • 17.6. 日期和時間屬性

    • 17.7. 屬性名

    • 17.8. 集合和計數

    • 17.9. 共同屬性命名

  • 18. 附錄

    • 18.1.1. Push notifications, per user flow

    • 18.1.2. Push notifications, firehose flow

    • 18.1. 時序圖注釋

3. 引言

開發人員通常通過HTTP接口訪問大多數微軟云平臺資源。雖然每個服務通常提供特定于語言框架來包裝其API,但它們的所有操作最終都歸結為HTTP請求。微軟必須支持廣泛的客戶端和服務,不能依賴于每個開發環境都有豐富的框架。因此,本指導原則的目標是確保Microsoft REST API能夠被任何具有基本HTTP支持的客戶端輕松且一致地使用。
[*]譯者注:本指南不限于微軟技術和平臺,廣泛適應于各種語言和平臺。

為了給開發人員提供最流暢的體驗,讓這些API遵循統一的設計準則是很重要的,從而使其簡單易用,符合人們的直覺反應。本文檔建立了 Microsoft REST API 開發人員應該遵循的指南, 以便統一一致地開發API。

一致性的好處在于可以不斷地積累合理的規范;一致性使團隊擁有統一的代碼、模式、文檔風格和設計策略。

這些準則旨在達成如下目標:

  • 為Microsoft技術平臺所有API端點定義一致的實現和體驗。

  • 盡可能地遵循行業普遍接受的 REST/HTTP 最佳實踐。

  • 讓所有應用開發者都可以輕松的通過REST接口訪問Micosoft服務。

  • 允許Service開發者利用其他Service的基礎上來開發一致的REST API端點。

  • 允許合作伙伴(例如,非Micosoft團隊)使用這些準則來設計自己的 REST API。
    [*]注:本指南旨在構建符合 REST 架構風格的服務,但不涉及或要求構建遵循 REST 約束的服務。
    本文檔中使用的“REST”術語代指具有 RESTful風格的服務,而不是僅僅遵循 REST。

3.1 推薦閱讀

了解REST架構風格背后的理念,更有助于開發優秀的基于 HTTP 的服務。
如果您對 RESTful 設計不熟悉,請參閱以下優秀資源:

  • REST on Wikipedia — 維基百科上關于REST的核心概念與思想的介紹。

  • REST論文—— Roy Fielding網絡架構論文中關于REST的章節,“架構風格與基于網絡的軟件體系結構設計”

  • RFC 7231—— 定義HTTP/1.1 語義規范的權威資源。

  • REST 實踐—— 關于REST的基礎知識的入門書。

[*]譯者注:上一篇說了,REST 指的是一組架構約束條件和原則。那么滿足這些約束條件和原則的應用程序或設計就是 RESTful。

4. 解讀指導

4.1 應用指南

這些準則適用于Microsoft或任何合作伙伴服務公開的任何REST API。私有或內部API也應該嘗試遵循這些準則,因為內部服務最終可能會被公開。保證一致性不僅對外部客戶有價值,對內部服務使用者也很有價值,而這些準則為對任何服務都提供了最佳實踐。
有合理理由可不遵循這些準則。如:實現或必須與某些外部定義的REST API互操作的REST服務必須與哪些外部的API兼容,而無法遵循這些準則。而還有一些服務也可能具有需要特殊性能需求,必須采用其他格式,例如二進制協議。

4.2 現有服務和服務版本控制的指南

我們不建議僅僅為了遵從指南而對這些指南之前的舊服務進行重大更改。無論如何,當兼容性被破壞時,該服務應該嘗試在下一版本發布時變得合規。
當一個服務添加一個新的API時,該API應該與同一版本的其他API保持一致。
因此,如果服務是針對 1.0 版本的指南編寫的,那么增量添加到服務的新 API 也應該遵循 1.0 版本指南。然后該服務在下一次主要版本更新時,再去遵循最新版指南。

4.3 要求語言

本文檔中的”MUST”(必須), “MUST NOT”(禁止), “REQUIRED”(需要), “SHALL”(將要), “SHALL NOT”(最好不要), “SHOULD”(應該), “SHOULD NOT”(不應該), “RECOMMENDED”(推薦), “MAY”(可能), 和 “OPTIONAL”(可選) 等關鍵字的詳細解釋見 RFC 2119。

4.4 許可證

本作品根據知識共享署名4.0國際許可協議授權。如需查看本授權的副本,請訪問http://creativecommons.org/licenses/by/4.0/?或致函 PO Box 1866, Mountain View, CA 94042, USA.

[*]譯者注:署名 4.0 國際,也就是允許在任何媒介以任何形式復制、發行本作品,允許修改、轉換或以本作品為基礎進行創作。允許任何用途,甚至商業目的。

5. 分類

作為Microsoft REST API指南的一部分,服務必須符合下面定義的分類法。

5.1 錯誤

錯誤,或者更具體地說是服務錯誤,定義為因客戶端向服務傳遞錯誤數據,導致服務端拒絕該請求。示例包括無效憑證、錯誤的參數、未知的版本ID等。客戶端傳遞錯誤的或者不合法的數據的情況通常返回 “4XX” 的 HTTP 錯誤代碼。

錯誤不會影響API的整體可用性。

[*]譯者注:錯誤可以理解成客戶端參數錯誤,通常返回“4XX”狀態碼,并不影響整體的API使用。

5.2 故障

故障(缺陷),或者更具體地說是服務故障,定義為服務無法正確返回數據以響應有效的客戶端請求。通常會返回“5xx”HTTP錯誤代碼。

故障會影響整體 API 的可用性。
由于速率限制(限流)或配額故障而失敗的調用不能算作故障。由于服務快速失敗(fast-failing)請求(通常是為了保護自己)而失敗的調用會被視為故障。

[*]譯者注:故障意味著服務端代碼出現故障,可能會影響整體的API使用。比如數據庫連接超時。
fast-failing 快速失敗
safe-failing 安全失敗

5.3 延遲

延遲定義為特定的API調用完成所需的時間(盡可能使用客戶端調用進行測量)。此測量方法同樣適用于同步和異步的API。對于長時間運行(long running calls)的調用,延遲定義為第一次調用它所需的時長,而不是整個操作)完成所需的時間。

[*]譯者注:Latency(延遲)是衡量軟件系統的最常見的指標之一,不僅僅和系統、架構的性能相關,還和網絡傳輸和延遲有關系。

5.4 完成時間

暴露長時間操作的服務必須跟蹤這些操作的 “完成時間” 指標。

5.5 長期運行API故障

對于長期運行的 API,很可能出現第一次請求成功,且后續每次去獲取結果時 API 也處于正常運行(每次都回傳 200)中,但其底層操作已經失敗了的情況。長期運行故障必須作為故障匯總到總體可用性指標中。

6. 客戶端指導

為確保客戶端更好的接入REST服務,客戶端應遵循以下最佳實踐:

6.1 忽略規則

對于松散耦合的客戶端調用,在調用之前不知道數據的確切定義和格式,如果服務器沒用返回客戶端預期的內容,客戶端必須安全地忽略它。

在服務迭代的過程中,有些服務(接口)可能在不更改版本號的情況下向響應添加字段。此類服務必須在其文檔中注明,客戶端必須忽略這些未知字段。

[*]譯者注:一個已發布的在線接口服務,如果不修改版本而增加字段,那么一定不能影響已有的客戶端調用。

6.2 變量排序規則

客戶端處理響應數據時一定不能依賴服務端JSON響應數據字段的順序。例如,例如,當服務器返回的 JSON 對象中的字段順序發生變化,客戶端應當能夠正確進行解析處理。
當服務端支持時,客戶端可以請求以特定的順序返回數據。例如,服務端可能支持使用$orderBy querystring參數來指定JSON數組中元素的順序。
服務端也可以在協議中顯式說明指定某些元素按特定方式進行排序。例如,服務端可以每次返回 JSON 對象時都把 JSON 對象的類型信息作為第一個字段返回,進而簡化客戶端解析返回數據格式的難度。客戶端處理數據時可以依賴于服務端明確指定了的排序行為。

6.3 無聲失效規則

當客戶端請求帶可選功能參數的服務時(例如帶可選的頭部信息),必須對服務端的返回格式有一定兼容性,可以忽略某些特定功能。

[*]譯者注:例如分頁數、排序等自定義參數的支持和返回格式的兼容。

7. 基礎原則

7.1 URL結構

URL必須保證友好的可讀性與可構造性,人類應該能夠輕松地讀取和構造url。:)
這有助于用戶發現并簡化接口的調用,即使平臺沒有良好的客戶端SDK支持。
[*]譯者注:API URL路徑結構應該是友好的易于理解的。甚至用戶無需通過閱讀API文檔能夠猜出相關結構和路徑。

結構良好的URL的一個例子是:
https://api.contoso.com/v1.0/people/jdoe@contoso.com/inbox
[*]譯者注:通過以上URL我們可以獲知API的版本、people資源、用戶標識(郵箱)、收件箱,而且很容易獲知——這是jdoe的收件箱的API。

一個不友好的示例URL是:
https://api.contoso.com/EWS/OData/Users('jdoe@microsoft.com')/Folders('AAMkADdiYzI1MjUzLTk4MjQtNDQ1Yy05YjJkLWNlMzMzYmIzNTY0MwAuAAAAAACzMsPHYH6HQoSwfdpDx-2bAQCXhUk6PC1dS7AERFluCgBfAAABo58UAAA=')
[*]譯者注:這是ODATA的API,不過目錄標識不易于理解,沒什么意義。

出現的常見模式是使用URL作為值(參數)。服務可以使用URL作為值。
例如,以下內容是可以接受的(URL中,url參數傳遞了花式的鞋子這個資源):
https://api.contoso.com/v1.0/items?url=https://resources.contoso.com/shoes/fancy
[*]譯者注:Token第三方認證中把登陸前來源地址返回給客戶端。

7.2 URL長度

HTTP 1.1消息格式(在第3.1.1節的RFC 7230中定義)對請求沒有長度限制,其中包括目標URL。RFC的:

HTTP沒有對請求行長度設置預定義的限制。[…如果服務器接收到的請求目標比它希望解析的任何URI都長,那么它必須使用 414 (URI太長)狀態代碼進行響應。

服務如果能夠生成超過2,083個字符的url,必須考慮兼容它支持的客戶端。不同客戶端支持的最長 URL 長度參見以下資料:

  • http://stackoverflow.com/a/417184

  • https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/

還請注意,一些技術棧有強制的的URL限定,所以在設計服務時要記住這一點。

7.3 規范標識符

除了提供友好的URL之外,能夠移動或重命名的資源必須包含唯一穩定的標識符。
在與 服務 進行交互時可能需要通過友好的名稱來獲取資源固定的 URL,就像某些服務使用的“/my”快捷方式一樣。
指南不強制要求 固定標識符使用GUID。
包含規范標識符的URL的一個例子是(標識符比較友好):
https://api.contoso.com/v1.0/people/7011042402/inbox

[]譯者注:一般是暴露主鍵字段,也可以是其他唯一的易于理解的字段,比如姓名、標題、郵箱等等。
[]譯者注:GUID太長而且不易于理解和閱讀,如果不是必須,盡量少用此字段。

7.4 支持方法

客戶端必須盡可能使用正確的HTTP動詞來執行操作,并且必須考慮是否支持此操作的冪等性。HTTP方法通常稱為HTTP動詞。

在此上下文中,術語是同義詞,但是HTTP規范使用術語方法。

下面是Microsoft REST服務應該支持的方法列表。并不是所有資源都支持所有方法,但是使用以下方法的所有資源必須符合它們的用法。

| Method | Description | Is Idempotent
|:–|:–|
| GET | 返回對象的當前值 | True
| PUT | 在適用時替換對象,或創建命名對象 | True
| DELETE | 刪除對象 | True
| POST | 根據提供的數據創建一個新對象,或者提交一個操作 | False
| HEAD | 返回GET響應的對象的元數據。支持GET方法的資源也可能支持HEAD方法 | True
| PATCH | 更新對象部分應用 | False
| OPTIONS | 獲取關于請求的信息;詳見下文。| True

7.4.1 POST

POST操作應該支持重定向響應標頭(Location),以便通過重定向標頭返回創建好的資源的鏈接。

例如,假設一個服務允許創建并命名托管服務器:

POST?http://api.contoso.com/account1/servers
響應應該是這樣的:

201 Created
Location:http://api.contoso.com/account1/servers/server321

其中“server321”是服務分配的服務器名。

服務還可以在響應中返回已創建項的完整元數據。

7.4.2. PATCH

PATCH已被IETF標準化為用于增量更新現有對象的方法(參見RFC 5789)。符合Microsoft REST API準則的API應該支持PATCH。

7.4.3. Creating resources via PATCH (UPSERT semantics) 通過 PATCH 創建資源(UPSERT 定義)

允許客戶端在創建資源的時候只指定部分鍵值(key)數據的必須支持UPSET語義,該服務必須支持以PATCH動詞來創建資源。

鑒于PUT被定義為內容的完全替換,所以客戶端使用PUT修改數據是危險的。

當試圖更新資源時,不理解(并因此忽略)資源的某些屬性的客戶端,很可能在PUT上忽視這些屬性,導致提交后這些屬性可能在不經意間被刪除。

所以,如果選擇支持PUT來更新現有資源,則必須是完整替換(即,PUT之后,資源的屬性必須匹配請求中提供的內容,包括刪除沒有提供的任何服務端的屬性)。

在UPSERT語義下,對不存在資源的 PATCH 調用,由服務器作為“創建”處理,對已存在的資源的 PATCH 調用作為“更新”處理。
為了確保更新請求不被視為創建(反之亦然),客戶端可以在請求中指定預先定義的 HTTP 請求頭。

  • 如果 PATCH 請求包含if-match標頭,則服務不能將其視為插入;如果 PATCH 請求包含值為 “*” 的if-none-match頭,則服務不能將其視為更新。

如果服務不支持UPSERT,則針對不存在的資源的 PATCH 調用必須導致 HTTP “409 Conflict”錯誤。

7.4.4 Options 標頭 和 link headers 標簽

OPTIONS 允許客戶端查詢某個資源的元信息,并至少可以通過返回支持該資源的有效方法(支持的動詞類別)的Allow 標頭。
[*]譯者注:當發起跨域請求時,瀏覽器會自動發起OPTIONS請求進行檢查。

此外,建議服務返回應該包括一個指向有關資源的穩定鏈接(Link header)(見RFC 5988):

Link: <{help}>; rel="help"

其中{help}是指向文檔資源的URL。

有關選項使用的示例,請參見完善CORS跨域調用。

7.5 標準的請求標頭

下面的請求標頭表 應該遵循 Microsoft REST API指南服務使用。使用這些標題不是強制性的,但如果使用它們則必須始終一致地使用。

所有標頭值都必須遵循規范中規定的標頭字段所規定的語法規則。許多HTTP標頭在RFC7231中定義,但是在IANA標頭注冊表中可以找到完整的已批準頭列表。

Header 標頭Type 類型Description 描述
AuthorizationString請求的授權標頭
DateDate請求的時間戳,基于客戶端的時鐘,采用RFC 5322日期和時間格式。服務器不應該對客戶端時鐘的準確性做任何假設。此標頭可以包含在請求中,但在提供時必須采用此格式。當提供此報頭時,必須使用格林尼治平均時間(GMT)作為時區參考。例如:Wed, 24 Aug 2016 18:41:30 GMT. 請注意,GMT正好等于UTC(協調世界時)。
AcceptContent type響應請求的內容類型,如:
- application/xml

- text/xml

- application/json

- text/javascript (for JSONP)

根據HTTP準則,這只是一個提示,響應可能有不同的內容類型,例如blob fetch,其中成功的響應將只是blob流作為有效負載。對于遵循OData的服務,應該遵循OData中指定的首選項順序。

Accept-EncodingGzip, deflate如果適用,REST端點應該支持GZIP和DEFLATE編碼。對于非常大的資源,服務可能會忽略并返回未壓縮的數據。
Accept-Language“en”, “es”, etc.指定響應的首選語言。不需要服務來支持這一點,但是如果一個服務支持本地化,那么它必須通過Accept-Language頭來支持本地化。
Accept-CharsetCharset type like “UTF-8”
默認值是UTF-8,但服務應該能夠處理ISO-8859-1

Content-TypeContent typeMime type of request body (PUT/POST/PATCH)
Preferreturn=minimal, return=representation如果指定了return = minimal首選項,則服務應該返回一個空主體(empty body)以響應一次成功插入或更新。如果指定了return = representation,則服務應該在響應中返回創建或更新的資源。如果服務的場景中客戶端有時會從響應中獲益,但有時響應會對帶寬造成太大的影響,那么它們應該支持這個報頭。
If-Match, If-None-Match, If-RangeString使用樂觀并發控制支持資源更新的服務必須支持If-Match標頭。服務也可以使用其他與ETag相關的頭,只要它們遵循HTTP規范。

7.6 標準響應標頭

服務應該返回以下響應標頭,除非在“required”列中注明。

| Response Header | Required | Description |
| 響應報頭 | 必填 | 描述 |
|:–|:–|:–|
| Date | All responses | 根據服務器的時鐘,以RFC 5322日期和時間格式處理響應。這個頭必須包含在響應中。此報頭必須使用格林尼治平均時間(GMT)作為時區參考。例如:Wed, 24 Aug 2016 18:41:30 GMT.請注意,GMT正好等于協調世界時(UTC)。|
| Content-Type | All responses| 內容類型 |
| Content-Encoding | All responses | GZIP或DEFLATE,視情況而定 |
| Preference-Applied | 在請求中指定時 | 是否應用了首選項請求頭中指示的首選項 |
| ETag | 當請求的資源具有實體標記時 | ETag響應頭字段為請求的變量提供實體標記的當前值。與If-Match、If-None-Match和If-Range一起使用,實現樂觀并發控制。|

7.7. 自定義標頭

基本的API操作不應該支持自定義標頭。

本文檔中的一些準則規定了非標準HTTP標頭的使用。此外,某些服務可能需要添加額外的功能,這些功能通過HTTP標頭文件公開。以下準則有助于在使用自定義標頭時保持一致性。

非標準HTTP標頭必須具有以下兩種格式之一:

  • 使用IANA(RFC 3864)注冊為“臨時”的標頭的通用格式

  • 為注冊使用過特定的頭文件的范圍格式
    這兩種格式如下所述。

  • 7.8. 以查詢參數方式提交自定義請求頭

    有些標頭對某些場景(如AJAX客戶端)不兼容,特別是在不支持添加標頭的跨域調用時。因此,除了常見的標頭信息外,一些標頭信息可以允許被作為查詢參數傳遞給服務端,其命名與請求頭中的名稱保持一致:

    并不是所有的標頭都可以用作查詢參數,包括大多數標準HTTP標頭。
    考慮何時接受標頭作為參數的標準如下:

  • 任何自定義標頭也必須作為參數接受。

  • 請求的標準標頭也可以作為參數接受。

  • 具有安全敏感性的必需標頭(例如,授權標頭 Authorization)可能不適合作為參數;服務所有者應該具體情況具體分析。

  • 此規則的一個例外是Accept頭。使用具有簡單名稱的方案,而不是使用HTTP規范中描述的用于Accept的完整功能,這是一種常見的實踐。

    7.9. PII 個人身份信息參數

    與普遍的隱私政策一致,客戶端不應該在URL中傳輸個人身份信息(PII)參數(作為路徑或查詢參數),因為這些信息可能通過客戶端、網絡和服務器日志和其他機制無意暴露出來。

    因此,服務應該接受PII參數作為標頭傳輸。

    然而在實踐中,由于客戶端或軟件的限制,在許多情況下無法遵循上述建議。為了解決這些限制,服務也應該接受這些PII參數作為URL的一部分,與本指導原則的其余部分保持一致。

    接受PII參數(無論是在URL中還是作為標頭)的服務 應該符合其組織的隱私保護原則。通常建議包括:客戶端使用標頭進行加密傳輸,并且實現要遵循特殊的預防措施,以確保日志和其他服務數據收集得到正確的處理。

    [*]譯者注:PII——個人可標識信息。比如家庭地址,身份證信息。

    7.10. Response formats 響應格式

    一個成功的平臺,往往提供可讀性較好并且一致的響應結果,并允許開發人員使用公共 Http 代碼處理響應。

    基于Web的通信,特別是當涉及移動端或其他低帶寬客戶端時,我們推薦使用JSON作為傳輸格式。主要是由于其更輕量以及易于與JavaScript交互。

    JSON屬性名應該采用camelCasedE駝峰命名規范。

    服務應該提供JSON作為默認輸出格式。

    7.10.1 Clients-specified 客戶端指定響應格式

    在HTTP中,客戶端應該使用Accept頭請求響應格式。服務端可以選擇性的忽略,如客戶端發送多個Accept標頭,服務可以選擇其中一個格式進行響應。

    默認的響應格式(沒有提供Accept頭)應該是application/json,并且所有服務必須支持application/json。

    | Accept Header | Response type | Notes |
    | 接受標頭 | 響應類型 | 備注 |
    |:–|:–|:–|
    | application/json | 必須是返回json格式 | 同樣接受JSONP請求的text/JavaScript |

    Accept: application/json

    7.10.2 錯誤的條件響應

    對于調用不成功的情況,開發人員應該能夠用相同的代碼庫一致地處理錯誤。這允許構建簡單可靠的基礎架構來處理異常,將異常作為成功響應的獨立處理流程來處理。下面的代碼基于OData v4 JSON規范。但是,它非常通用,不需要特定的OData構造。即使api沒有使用其他OData結構,也應該使用這種格式。

    錯誤響應必須是單個JSON對象。該對象必須有一個名為“error”的 名稱/值(name/value) 對。該值必須是JSON對象。

    這個對象必須包含名稱“code”和“message”的 鍵值對,并且它建議包含譬如“target”、“details”和 “innererror” 的鍵值對。

    “code”鍵值對的值 是一個與語言無關的字符串。它的值是該服端務定義的錯誤代碼,應該簡單可讀。與響應中指定的HTTP錯誤代碼相比,此代碼用作錯誤的更具體的指示。服務應該具有相對較少的“code”數量(別超過20個),并且所有客戶端必須能夠處理所有這些錯誤信息。
    大多數服務將需要更大數量的更具體的錯誤代碼以滿足所有的客戶端請求。這些錯誤代碼應該在“innererror” 鍵值對中公開,如下所述。為現有客戶端可見的“代碼”引入新值是一個破壞性的更改,需要增加版本。服務可以通過向“innererror”添加新的錯誤代碼來避免中斷服務更改。

    “message”鍵值對的值 必須是錯誤提示消息,必須是可讀且易于理解。它旨在是幫助開發人員,不適合暴露給最終用戶。想要為最終用戶公開合適消息的服務必須通過annotation注釋或其他自定義屬性來公開。服務不應該為最終用戶本地化“message”,因為這樣對于開發者變得非常不友好并且難以處理。

    “target”鍵值對的值 是指向錯誤的具體的目標(例如,錯誤中屬性的名稱)。

    “details”鍵值對的值 必須是JSON對象數組,其中必須包含“code”和“message”的鍵值對,還可能包含“target”的鍵值對,如上所述。“details”數組中的對象通常表示請求期間發生的不同的、相關的錯誤。請參見下面的例子。

    “innererror”鍵值對的值 必須是一個對象。這個對象的內容是服務端定義的。想要返回比根級別代碼更具體的錯誤的服務,必須包含“code”的鍵值對和嵌套的“innererror”。每個嵌套的“innererror”對象表示比其父對象更高層次的細節。在評估錯誤時,客戶端必須遍歷所有嵌套的“內部錯誤”,并選擇他們能夠理解的最深的一個。這個方案允許服務在層次結構的任何地方引入新的錯誤代碼,而不破壞向后兼容性,只要舊的錯誤代碼仍然出現。服務可以向不同的調用者返回不同級別的深度和細節。例如,在開發環境中,最深的“innererror”可能包含有助于調試服務的內部信息。為了防范信息公開帶來的潛在安全問題,服務應注意不要無意中暴露過多的細節。錯誤對象還可以包括特定于代碼的自定義服務器定義的鍵值對。帶有自定義服務器定義屬性的錯誤類型應該在服務的元數據文檔中聲明。請參見下面的例子。

    錯誤響應返回的的任何JSON對象中都可能包含注釋。

    我們建議,對于任何可能重試的臨時錯誤,服務應該包含一個 Retry-After HTTP頭,告訴客戶端在再次嘗試操作之前應該等待的最小秒數。

    ErrorResponse : Object
    PropertyTypeRequiredDescription
    errorError?The error object.
    Error : Object
    PropertyTypeRequiredDescription
    codeString (enumerated)?服務器定義的錯誤代碼集之一。message
    targetString
    The target of the error.
    detailsError[]
    An array of details about specific errors that led to this reported error.
    innererrorInnerError
    An object containing more specific information than the current object about the error.
    InnerError : Object
    PropertyTypeRequiredDescription
    codeString
    A more specific error code than was provided by the containing error.
    innererrorInnerError
    An object containing more specific information than the current object about the error.
    Examples

    內部錯誤的例子:

    { "error": { "code": "BadArgument", "message": "Previous passwords may not be reused", "target": "password", "innererror": { "code": "PasswordError", "innererror": { "code": "PasswordDoesNotMeetPolicy", "minLength": "6", "maxLength": "64", "characterTypes": ["lowerCase","upperCase","number","symbol"], "minDistinctCharacterTypes": "2", "innererror": { "code": "PasswordReuseNotAllowed" } } } }}

    在本例中,基本的錯誤代碼是“BadArgument”,但是對于感興趣的客戶端,“innererror”中提供了更具體的錯誤代碼。
    “passwordreusenotal”代碼可能是在之后的迭代中由該服務添加的,之前只返回“passwordnotmeetpolicy”。
    這種增量型的添加方式并不會破壞老的客戶端的處理過程,而又可以給開發者一些更詳細的信息。
    “PasswordDoesNotMeetPolicy”錯誤還包括額外的鍵值對,這些鍵值對 允許客戶機確定服務器的配置、以編程方式驗證用戶的輸入,或者在客戶機自己的本地化消息傳遞中向用戶顯示服務器的約束。

    詳細的例子 “details”:

    { "error": { "code": "BadArgument", "message": "Multiple errors in ContactInfo data", "target": "ContactInfo", "details": [ { "code": "NullValue", "target": "PhoneNumber", "message": "Phone number must not be null" }, { "code": "NullValue", "target": "LastName", "message": "Last name must not be null" }, { "code": "MalformedValue", "target": "Address", "message": "Address is not valid" } ] }}

    在本例中,請求存在多處問題,每個錯誤都列在 “details” 字段中進行返回了。

    7.11 HTTP狀態代碼 HTTP Status Codes

    應使用標準HTTP狀態碼作為響應狀態碼; 更多信息,請參見HTTP狀態代碼定義。

    7.12. 客戶端庫可選 Client library optional

    開發人員必須能夠在各種平臺和語言上進行開發,比如Windows、macOS、Linux、c#、Python和Node.js或是Ruby。

    服務應該能夠讓簡單的HTTP工具(如curl)進行訪問,而不需要做太多的工作。

    該服務提供給開發人員的網站應該提供相當于“獲得開發者令牌(Get developer Token)的功能,以幫助開發人員測試并應提供curl支持。

    8. CORS 跨域

    符合Microsoft REST API準則的服務必須支持CORS(跨源資源共享)。
    服務應該支持CORS *的允許起源,并通過有效的OAuth令牌強制授權。
    服務不應該支持帶有源驗證的用戶憑據。
    特殊情況可例外。

    8.1. 客戶端指導

    Web開發人員通常不需要做任何特殊處理來利用CORS。
    作為標準XMLHttpRequest調用的一部分,所有握手步驟都是不可見的。

    許多其他平臺(如.NET)已集成了對CORS的支持。

    8.1.1. 避免額外的預檢查

    由于CORS協議會觸發向服務器添加額外往返的預檢請求,因此,注重性能的應用程序可能會有意避免這些請求。
    CORS背后的精神是避免對舊的不支持CORS功能的瀏覽器能夠做出的任何簡單的跨域請求進行預檢。
    所有其他請求都需要預檢。

    請求是“簡單類型請求“,如果其方法是GET,HEAD或POST,并且除了Accept,Accept-Language和Content-Language之外它不包含任何請求標頭,則可以免去預檢。

    對于POST請求,也允許使用Content-Type標頭,但前提是其值為“application/x-www-form-urlencoded”,“multipart/form-data”或“text/plain”。
    對于任何其他標頭或值,將發生預檢請求。

    8.2. 服務指南

    服務必須至少:

    • 了解瀏覽器在跨域請求上發送的Origin請求標頭,以及他們在檢查訪問權限的預檢OPTIONS 請求上發送的 Access-Control-Request-Method請求標頭。

    • 如果請求中存在Origin標頭:

      • 添加一個Access-Control-Allow-Headers響應標頭,其中包含允許客戶端使用的請求標頭名稱列表。這個列表只需要包含不在[簡單請求頭][rs-simple-headers] (Accept、Accept- language、Content-Language)集合中的頭。如果服務接受的報頭沒有限制,則服務可以簡單地返回與客戶機發送的訪問-控制-請求-報頭報頭相同的值。

      • 添加一個Access-Control-Allow-Methods響應頭,其中包含允許調用方使用的HTTP方法列表。

      • 如果請求使用 OPTIONS 方法并包含 Access-Control-Request-Method標頭,則它是一個預檢請求,用于在實際請求之前探測訪問。否則,這是一個實際的請求。對于預檢請求,除了執行以下步驟添加標頭之外,服務必須不執行任何額外處理,并且必須返回 200 OK。對于非預檢請求,除了請求的常規處理之外,還會添加以下標頭。

      • 服務向響應添加 Access-Control-Allow-Origin 標頭,其中包含與Origin 請求標頭相同的值。請注意,這需要服務來動態生成標頭值。不需要cookie或任何其他形式的[用戶憑證]?cors-user-credentials的資源可以使用通配符星號(*)進行響應。請注意,通配符僅在此處可接受,而不適用于下面描述的任何其他標頭。

      • 如果調用者需要訪問不屬于[簡單響應頭]?cors-simple-headers集合中的響應頭(Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma),同時添加一個Access-Control-Expose-Headers標頭,其中包含客戶端應有權訪問的其他響應標頭名稱列表。
        [*]譯者注:在跨域請求時,響應中的大部分header,需要服務端同意才能拿到,客戶端跨域增加 Access-Control-Expose-Headers: content-type, cache …… 等標頭來告知服務器。

      • 如果請求需要cookie,則添加一個Access-Control-Allow-Credentials頭,并將其設置為“true”。

      • 如果請求是預檢請求(見第一個項目符號),則服務必須滿足:

    添加一個Access-Control-Max-Age pref

    響應頭,其中包含此預檢前響應有效的秒數(因此可以在后續實際請求之前避免)。注意,雖然習慣上使用較大的值,比如2592000(30天),但是許多瀏覽器會自動設置一個更低的限制(例如,5分鐘)。

    眾所周知,由于瀏覽器預檢響應緩存很弱,因此預檢響應的額外往返會損害性能。
    [*]譯者注:獲取預檢OPTIONS調用會造成很大開銷,而且也瀏覽器的緩存能力也很贏弱,而且部分瀏覽器也不會理會access-control-max-age的設置值,如Chrome/Blink 就硬編碼為10分鐘(600秒)。詳見[https://chromium.googlesource.com/chromium/blink/+/master/Source/core/loader/CrossOriginPreflightResultCache.cpp#40]

    注重性能端的交互式 Web客戶端使用的服務端應該避免使用導致預檢的請求。

    • 對于GET和HEAD調用,請避免要求不屬于上述簡單集的請求標頭。最好是允許將它們作為查詢參數提供。

      • Authorization標頭不是簡單集的一部分,因此對于需要驗證的資源,必須通過“access_token”查詢參數發送驗證令牌。請注意,不建議在URL中傳遞身份驗證令牌,因為它可能導致令牌記錄在服務器日志中,并暴露給有權訪問這些日志的任何人。通過URL接受身份驗證令牌的服務必須采取措施來降低安全風險,例如使用短期身份驗證令牌,禁止記錄身份驗證令牌以及控制對服務器日志的訪問。

    • 避免要求cookie。如果設置了“withCredentials”屬性,XmlHttpRequest將僅在跨域請求上發送cookie; 這也會導致預檢請求。

      • 需要基于cookie的身份驗證的服務必須使用“動態驗證碼(dynamic canary)” [*]譯者注:服務器生成某種驗證碼,客戶端獲取后,服務器再進行驗證的操作。來保護所有接受cookie的API。

    • 對于POST調用,在適用的情況下,選擇簡單的內容類型(“application/x-www-form-urlencoded”、“multipart/form-data”、“text/plain”)。其他任何內容類型都會引發預檢請求。

      • 服務不得以避免CORS預檢請求的名義違反其他API指南。由于內容類型的原因,大多數POST請求實際上需要預檢請求。

      • 如果非要取消預檢工作,那么服務支持的其他的替代數據傳輸機制必須遵循本指南。

    此外,當適當的服務可以支持JSONP模式時,只需簡單的GET跨域訪問。
    在JSONP中,服務采用指示格式的參數($format=json)和表示回調的參數($callback=someFunc),并返回一個 text/javascript 文檔,其中包含用指定名稱封裝在函數調用中的JSON響應。
    更多關于JSONP的信息,請訪問Wikipedia:?JSONP。

    9. 集合 Collections

    9.1. Item keys

    服務可以支持集合中每個項的持久標識符(主鍵),該標識符應用JSON表示為”id” , 這些持久標識符通常用作項目的key。

    支持持久標識符(主鍵)的集合可以支持增量查詢。

    9.2. 序列化 Serialization

    集合使用標準數組表示法以JSON表示。

    9.3. Collection URL patterns 集合的URL匹配

    集合在頂級時直接位于服務的根目錄下,或者作用于該資源時作為另一個資源下的段。

    例如:

    GET https://api.contoso.com/v1.0/people

    服務必須盡可能支持“/” 匹配。
    例如:

    GET https://{serviceRoot}/{collection}/{id}

    Where:

    • {serviceRoot} – 站點URL (site URL) + 服務的根路徑的組合

    • {collection} – 集合的名稱,未縮寫,復數

    • {id} – 唯一id屬性的值. 當使用 “/“ 匹配必須屬于 string/number/guid value 不帶引號,轉義正確以適應URL。

    9.3.1. 嵌套集合和屬性 Nested collections and properties

    集合項可以包含其他集合。
    例如,用戶集合可能包含多個地址的用戶資源:

    GET https://api.contoso.com/v1.0/people/123/addresses{ "value": [ { "street": "1st Avenue", "city": "Seattle" }, { "street": "124th Ave NE", "city": "Redmond" } ]}

    9.4. 大集合 Big collections

    隨著數據的增長,集合也在增長。所以計劃采用分頁對所有服務都很重要。
    因此,當數據包含多頁時,序列化有效負載(payload)必須適當地包含下一頁的不透明URL。
    有關詳細信息,請參閱分頁指南。

    客戶端必須能夠恰當的處理請求返回的任何給定的分頁或非分頁集合數據。

    { "value":[ { "id": "Item 1","price": 99.95,"sizes": null}, { … }, { … }, { "id": "Item 99","price": 59.99,"sizes": null} ], "@nextLink": "{opaqueUrl}"}

    9.5. Changing collections

    POST請求不是冪等的。
    這意味著發送到具有完全相同的有效負載(payload)的集合資源的兩次POST請求可能導致在該集合中創建多個項。
    [*]譯者注:相同的數據兩次POST操作,可能導致該集合創建多次。
    例如,對于具有服務器端生成的id的項的插入操作,通常就是這種情況。

    例如,以下請求:

    POST https://api.contoso.com/v1.0/people

    會導致響應,指示新集合項的位置:

    201 CreatedLocation: https://api.contoso.com/v1.0/people/123

    一旦再次執行,可能會導致創建另一個資源:

    201 CreatedLocation: https://api.contoso.com/v1.0/people/124

    而PUT請求則需要使用相應的鍵來指示集合項:

    PUT https://api.contoso.com/v1.0/people/123

    9.6. Sorting collections

    可以基于屬性值對集合查詢的結果進行排序。
    該屬性由_$orderBy_查詢參數的值確定。

    $orderBy?參數的值包含用于對項目進行排序表達式列表,用逗號分隔的。
    這種表達式的特殊情況是屬性路徑終止于基本屬性。

    表達式可以包含升序的后綴“asc”或降序的后綴“desc”,它們與屬性名之間用一個或多個空格分隔。
    如果沒有指定“asc”或“desc”,則服務必須按照指定的屬性以升序排序。

    空值(NULL)必須排序為“小于”非空值。

    必須根據第一個表達式的結果值對項進行排序,然后根據第二個表達式的結果值對第一個表達式具有相同值的項進行排序,以此類推。
    排序順序是屬性類型的固有順序。

    例如:

    GET https://api.contoso.com/v1.0/people?$orderBy=name

    將返回按name進行升序排序的所有人員。

    GET https://api.contoso.com/v1.0/people?$orderBy=name desc

    將返回按name進行降序排序的所有人。

    可以通過逗號分隔的屬性名稱列表以及可選方向限定符來指定子排序。

    例如:

    GET https://api.contoso.com/v1.0/people?$orderBy=name desc,hireDate

    將返回按姓名降序排列的所有人員,并按雇傭日期降序排列的次要排序。

    排序必須與篩選相結合,如下:

    GET https://api.contoso.com/v1.0/people?$filter=name eq 'david'&$orderBy=hireDate

    將返回所有名稱為David的人,按雇傭日期按升序排列。

    9.6.1. Interpreting a sorting expression

    跨頁面的排序參數必須一致,因為客戶端和服務器端分頁都依賴該排序該參數進行排序。

    如果服務不支持按_$orderBy_表達式中命名的屬性排序,則服務必須按照“響應不支持的請求”部分中定義的錯誤消息進行響應。

    9.7. Filtering

    $filter_querystring 參數允許客戶端通過URL過濾集合。
    使用_$filter_指定的表達式將為集合中的每個資源求值,只有表達式求值為true的項才包含在響應中。
    表達式計算為false或null的資源,或由于權限而不可用的引用屬性,將從響應中省略。

    例如:返回所有產品的價格低于10.00美元

    GET https://api.contoso.com/v1.0/products?$filter=price lt 10.00

    $filter_選項的值是 一個布爾表達式 表示 price less than 10.00。

    9.7.1. Filter operations

    支持_$filter_的服務應該支持以下最小操作集。

    OperatorDescriptionExample
    Comparison Operators

    eqEqualcity eq ‘Redmond’
    neNot equalcity ne ‘London’
    gtGreater thanprice gt 20
    geGreater than or equalprice ge 10
    ltLess thanprice lt 20
    leLess than or equalprice le 100
    Logical Operators

    andLogical andprice le 200 and price gt 3.5
    orLogical orprice le 3.5 or price gt 200
    notLogical negationnot price le 3.5
    Grouping Operators

    ( )Precedence grouping(priority eq 1 or city eq ‘Redmond’) and price gt 100

    9.7.2. Operator examples

    下面的示例說明了每個邏輯操作符的用法和語義。

    示例:所有名稱等于“Milk”的產品

    GET https://api.contoso.com/v1.0/products?$filter=name eq 'Milk'

    示例:所有名稱不等于“Milk”的產品

    GET https://api.contoso.com/v1.0/products?$filter=name ne 'Milk'

    示例:所有標有“Milk”的產品價格都低于2.55:

    GET https://api.contoso.com/v1.0/products?$filter=name eq 'Milk' and price lt 2.55

    示例:所有標有“Milk”字樣或價格低于2.55美元的產品:

    GET https://api.contoso.com/v1.0/products?$filter=name eq 'Milk' or price lt 2.55

    示例:所有名稱為“牛奶”或“雞蛋”且價格低于2.55的產品:

    GET https://api.contoso.com/v1.0/products?$filter=(name eq 'Milk' or name eq 'Eggs') and price lt 2.55

    9.7.3. Operator precedence

    在計算_$filter_表達式時,服務使用以下操作符優先級。
    操作符按類別按優先級從高到低排列。
    同一類別的運算符具有同等優先級:
    | Group | Operator | Description |
    |:—————-|:———|:———————-|
    | Grouping | ( ) | Precedence grouping |
    | Unary | not | Logical Negation |
    | Relational | gt | Greater Than |
    | | ge | Greater than or Equal |
    | | lt | Less Than |
    | | le | Less than or Equal |
    | Equality | eq | Equal |
    | | ne | Not Equal |
    | Conditional AND | and | Logical And |
    | Conditional OR | or | Logical Or |

    9.8. Pagination

    返回集合的RESTful API可能返回部分集。
    這些服務的消費者清楚將獲得部分結果集,并能正確地翻頁以檢索整個結果集。

    RESTful API可能支持兩種形式的分頁。
    服務器驅動的分頁:通過在多個響應有效載荷上強制分頁請求來減輕拒絕服務攻擊。
    客戶端驅動的分頁:允許客戶機只請求它在給定時間可以使用的資源數量。

    跨頁面的排序和篩選參數必須一致,因為客戶端和服務器端分頁都完全兼容于篩選和排序。

    9.8.1. Server-driven paging

    分頁響應必須通過在響應中包含延續分頁標記來告訴客戶端這是部分結果。
    沒有延續分頁標記意味著沒有下一頁了。

    客戶端必須將延續URL視為不透明的,這意味著在迭代一組部分結果時,查詢選項可能不會更改。

    例如:

    GET http://api.contoso.com/v1.0/people HTTP/1.1Accept: application/jsonHTTP/1.1 200 OKContent-Type: application/json{ ..., "value": [...], "@nextLink": "{opaqueUrl}"}

    9.8.2. Client-driven paging

    客戶端可以使用$top_和$skip_查詢參數來指定返回的結果數量和跳過的集合數量。

    服務器應遵守客戶端指定的參數; 但是,客戶端必須做好準備處理包含不同頁面大小的響應或包含延續分頁標記的響應。

    當客戶端同時提供$top_和$skip_時,服務器應該首先應用$skip_,然后對集合應用$top_。

    注意:如果服務器不能執行$top_和/或$skip_,服務器必須返回一個錯誤給客戶端,告知它,而不是忽略該查詢參數。
    這將避免客戶端對返回的數據做出假設的風險。

    實例:

    GET http://api.contoso.com/v1.0/people?$top=5&$skip=2 HTTP/1.1Accept: application/jsonHTTP/1.1 200 OKContent-Type: application/json{ ..., "value": [...]}

    9.8.3. Additional considerations

    固定的順序先決條件:兩種分頁形式都依賴于具有固定順序的項的集合。
    服務器必須使用額外的排序(通常是按鍵排序)來補充任何指定的順序標準,以確保項目始終保持一致的順序。

    缺失/重復結果:即使服務器強制執行一致的排序順序,結果也可能會因創建或刪除其他資源而導致丟失或重復。
    客戶端必須準備好處理這些差異。
    服務器應該總是編碼最后讀取記錄的記錄ID,幫助客戶端管理重復/丟失的結果。

    結合客戶端和服務驅動的分頁:請注意,客戶端驅動的分頁不排除服務器驅動的分頁。
    如果客戶端請求的頁面大小大于服務器支持的默認頁面大小,則預期響應將是客戶端指定的結果數,否則按服務端分頁設置的指定分頁。

    頁面大小:客戶端可以通過指定_$maxpagesize_首選項來請求具有特定頁面大小的服務端驅動的分頁。
    如果指定的頁面大小小于服務端的默認頁面大小,服務器應該遵循此首選項。

    分頁嵌入式集合:客戶端驅動的分頁和服務端驅動的分頁都可以應用于嵌入式集合。
    如果服務端對嵌入式集合進行分頁,則必須包含其他適當的延續分頁標記。

    記錄集計數:想要知道所有頁面中的完整記錄數的開發人員可以包含查詢參數_$ count=true_,以告知服務端包含響應中的記錄數。

    9.9. Compound collection operations

    篩選、排序和分頁操作都可以針對給定的集合執行。
    當這些操作一起執行時,評估順序必須是:

  • 篩選。這包括作為AND操作執行的所有范圍表達式。

  • 排序。可能已過濾的列表根據排序條件進行排序。

  • 分頁。經過篩選和排序的列表上顯示了實現分頁視圖。這適用于服務器驅動的分頁和客戶端驅動的分頁。

  • 10. 增量查詢 Delta queries

    服務可以選擇支持Delta查詢。
    [*]譯者注:增量查詢可以使客戶端能夠發現新創建、更新或者刪除的實體,無需使用每個請求對目標資源執行完全讀取。這讓客戶端的調用更加高效。

    10.1. 增量鏈接 Delta links

    增量(Delta)鏈接是不透明的、由服務生成的鏈接,客戶端使用這些鏈接查詢對結果的后續更改。

    在概念層面上,delta鏈接基于一個定義查詢,該查詢描述正在跟蹤更改的一組結果集。
    delta鏈接編碼并跟蹤這些更改的實體集合,以及跟蹤更改的起點。

    如果查詢包含篩選器,則響應必須只包含對匹配指定條件的實體的更改。
    Delta查詢的主要原則是:

    • 集合中的每個項目必須具有持久標識符(永久不變的主鍵)。該標識符應該表示為“id”。此標識符由服務定義,客戶端可以使用該字符串跨調用跟蹤對象。

    • delta 必須包含每個與指定條件新匹配的實體的條目,并且必須為每個不再符合條件的實體包含“@removed”條目。

    • 重新調用查詢并將其與原始結果集進行比較; 必須將當前集合中惟一的每個條目作為”add”操作返回,并且必須將原始集合中惟一的每個條目作為“remove”操作返回。。

    • 以前與標準不匹配但現在匹配的每個實體必須作為”add”返回; 相反,先前與查詢匹配但不再必須返回的每個實體必須作為“@removed”條目返回。

    • 已更改的實體必須使用其標準表示形式包含在集合中。

    • 服務可以向“@remove”節點添加額外的元數據,例如刪除的原因或“removed at”時間戳。我們建議團隊與Microsoft REST API指導原則工作組協調,以幫助維護一致性。

    Delta鏈接不能編碼任何客戶端 top 或 skip 值。

    10.2. Entity representation

    添加和更新的實體使用其標準表示在實體集中表示。
    從集合的角度來看,添加或更新的實體之間沒有區別。

    刪除的實體僅使用其“id”和“@removed”節點表示。
    “@removed”節點的存在必須表示從集合中刪除條目。

    10.3. Obtaining a delta link

    通過查詢集合或實體并附加 $delta 查詢字符串參數來獲得 Delta 鏈接。

    例如:

    GET https://api.contoso.com/v1.0/people?$deltaHTTP/1.1Accept: application/jsonHTTP/1.1 200 OKContent-Type: application/json{ "value":[ { "id": "1", "name": "Matt"}, { "id": "2", "name": "Mark"}, { "id": "3", "name": "John"} ], "@deltaLink": "{opaqueUrl}"}

    注意:如果集合分頁,deltaLink將只出現在最后一頁,但必須反映對所有頁面返回的數據的任何更改。

    10.4. Contents of a delta link response

    添加/更新的條目必須以常規JSON對象的形式出現,并帶有常規項目屬性。
    在常規表示中返回添加/修改的項,允許客戶端使用基于“id”字段的標準合并概念將它們合并到現有的“緩存”中。

    從定義的集合中刪除的條目必須包含在響應中。
    從集合中刪除的項必須僅使用它們的“id”和“@remove”節點表示。

    10.5. Using a delta link

    客戶端通過調用delta鏈接上的GET方法請求更改。
    客戶端必須按原樣使用delta URL——換句話說,客戶端不能以任何方式修改URL(例如,解析URL并添加額外的查詢字符串參數)。

    在這個例子中:

    GET https://{opaqueUrl} HTTP/1.1Accept: application/jsonHTTP/1.1 200 OKContent-Type: application/json{ "value":[ { "id": "1", "name": "Mat"}, { "id": "2", "name": "Marc"}, { "id": "3", "@removed": {} }, { "id": "4", "name": "Luc"} ], "@deltaLink": "{opaqueUrl}"}

    針對delta鏈接的請求的結果可以跨多個頁面,但是必須由服務跨所有頁面進行排序,以便在應用到包含delta鏈接的響應時確保得到確定的結果。

    如果沒有發生任何更改,則響應是一個空集合,其中包含一個delta鏈接,用于根據請求進行后續更改。
    這個delta鏈接可能與delta鏈接相同,從而導致更改的空集合。

    如果delta鏈接不再有效,則服務必須使用_410 Gone_響應。響應應該包含一個Location頭,客戶端可以使用它來檢索新的基線結果集。


    如果喜歡作者的文章,請關注“DotNET技術圈”訂閱號以便第一時間獲得最新內容。本文版權歸作者和長沙.NET技術社區共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。?

    ?


    本文版權歸作者和長沙.NET技術社區共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


    總結

    以上是生活随笔為你收集整理的Microsoft REST API指南的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。