REST API設計指導——譯自Microsoft REST API Guidelines(四)

前言

前面咱們說了,若是API的設計更規範更合理,在很大程度上可以提升聯調的效率,下降溝通成本。那麼什麼是好的API設計?這裏咱們不得不提到REST API。javascript

 

關於REST API的書籍不少,可是完整完善實踐豐富的設計指導並很少見,咱們有幸看到了微軟團隊的做品——Microsoft REST API Guidelines,所以纔有了此篇內容。html

 

因爲公衆號文章內容字數有限,所以咱們將翻譯稿拆分並分享出來,而且給出英文對照。翻譯的不對之處,請多多指教。java

上篇內容:ios

REST API設計指導——譯自Microsoft REST API Guidelines(三)git

 

 

6 Client guidance 客戶指導

 

To ensure the best possible experience for clients talking to a REST service, clients SHOULD adhere to the following best practices:github

爲了保證與 REST API 服務進行對接的客戶端有更佳的體驗,客戶端應該遵循如下最佳實踐:編程

 

6.1 Ignore rule  忽略規則

For loosely coupled clients where the exact shape of the data is not known before the call, if the server returns something the client wasn't expecting, the client MUST safely ignore it.json

對於鬆散耦合的客戶端調用,在調用以前不知道數據的確切定義和格式,若是服務器沒用返回客戶端預期的內容,客戶端必須安全地忽略它。設計模式

 

Some services MAY add fields to responses without changing versions numbers.api

Services that do so MUST make this clear in their documentation and clients MUST ignore unknown fields.

有的服務(接口)能夠在響應中增長字段而不修改接口版本號。

若是有這種狀況,接口文檔中必須進行清晰明確地說明,而且客戶端必須忽略掉這些未知的字段。

PS:一個已發佈的在線接口服務,若是不修改版本而增長字段,那麼必定不能影響已有的客戶端調用。

 

6.2 Variable order rule 變量排序規則

Clients MUST NOT rely on the order in which data appears in JSON service responses.

客戶端處理響應數據時必定不能依賴服務端JSON 響應數據字段的順序。

PS:不要硬編碼,JSON反序列化了解一下。

 

For example, clients SHOULD be resilient to the reordering of fields within a JSON object.

例如,當服務器返回的 JSON 對象中的字段順序變了,客戶端應當可以正確進行解析處理。

 

When supported by the service, clients MAY request that data be returned in a specific order.

當服務端支持時,客戶端能夠請求有特定順序的數據。

PS:ODATA瞭解下,不只能排序,還能指定字段順序。

 

For example, services MAY support the use of the $orderBy querystring parameter to specify the order of elements within a JSON array.

例如,服務器能夠支持使用查詢參數 orderBy 來使服務器返回有序的 JSON 數組。

 

Services MAY also explicitly specify the ordering of some elements as part of the service contract.

服務端也能夠在協議中明確指定某些元素按特定方式進行排序。

PS:好比評論按點贊數倒序排序。

 

For example, a service MAY always return a JSON object's "type" information as the first field in an object to simplify response parsing on the client.

例如,服務端能夠每次返回 JSON 對象時都把 JSON 對象的類型信息做爲第一個字段返回,進而簡化客戶端解析返回數據格式的難度。

 

Clients MAY rely on ordering behavior explicitly identified by the service.

客戶端處理數據時能夠依賴於服務端明確指定了的排序行爲。

 

6.3 Silent fail rule 無聲失效規則

Clients requesting OPTIONAL server functionality (such as optional headers) MUST be resilient to the server ignoring that particular functionality.

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

PS:例如分頁數、排序等自定義參數的支持和返回格式的兼容。

 

7 Consistency fundamentals 基礎原則

 7.1 URL structure URL 結構

Humans SHOULD be able to easily read and construct URLs.

用戶應該可以輕鬆讀懂和理解URL的結構。

PS:API URL路徑結構應該是友好的易於理解的。甚至用戶無需經過閱讀API文檔可以猜出相關結構和路徑。

 

This facilitates discovery and eases adoption on platforms without a well-supported client library.

這有助於用戶發現並簡化接口的調用,即便平臺沒有良好的客戶端SDK支持。

PS:爲啥微信SDK那麼多,API不友好是很大的一個緣由。

 

An example of a well-structured URL is:

結構良好的 URL Demo:

 

https://api.contoso.com/v1.0/people/jdoe@contoso.com/inbox

PS:經過以上URL咱們能夠獲知API的版本、people資源、用戶標識(郵箱)、收件箱,並且很容易獲知——這是jdoe的收件箱的API。

 

An example URL that is not friendly is:

格式不友好的 URL Demo:

https://api.contoso.com/EWS/OData/Users('jdoe@microsoft.com')/Folders('AAMkADdiYzI1MjUzLTk4MjQtNDQ1Yy05YjJkLWNlMzMzYmIzNTY0MwAuAAAAAACzMsPHYH6HQoSwfdpDx-2bAQCXhUk6PC1dS7AERFluCgBfAAABo58UAAA=')

PS:這是ODATA的API,不過目錄標識不易於理解,沒什麼意義。

 

A frequent pattern that comes up is the use of URLs as values.

Services MAY use URLs as values.

For example, the following is acceptable:

一個常見的模式是使用 URL 做爲值(參數)。

服務能夠使用 URL 做爲值。

PS:國內使用這種設計模式的比較少見,更傾向因而一些更通用的API使用這種模式。

 

例以下例(URL中,url參數傳遞了花式的鞋子這個資源):

https://api.contoso.com/v1.0/items?url=https://resources.contoso.com/shoes/fancy

 

 

7.2 URL length 長度

The HTTP 1.1 message format, defined in RFC 7230, in section [3.1.1][rfc-7230-3-1-1], defines no length limit on the Request Line, which includes the target URL.

在 RFC 7230 [3.1.1] [rfc-7230-3-1-1] 章節中定義的 HTTP 1.1 消息格式,定義 請求(包括 URL)沒有長度限制。

 

From the RFC:

HTTP does not place a predefined limit on the length of a request-line. [...] A server that receives a request-target longer than any URI it wishes to parse MUST respond with a 414 (URI Too Long) status code.

 

HTTP不會對請求行的長度設置預約義的限制。 接收請求的目標服務若是發現當前URL長度超過預期解析的URI長度,必須響應414(URI 太長)HTTP狀態碼。

 

Services that can generate URLs longer than 2,083 characters MUST make accommodations for the clients they wish to support.

當 服務提供的 URL 長度超過 2083 個字符時必須考慮如何兼容全部將支持的客戶端。

 

Here are some sources for determining what target clients support:

不一樣客戶端支持的最長 URL 長度參見如下資料:

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

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

Also note that some technology stacks have hard and adjustable url limits, so keep this in mind as you design your services.

另請注意,某些技術棧對 url 限制有強制規定,所以請在設計服務時牢記這點。

 

7.3 Canonical identifier 規範的標識符

In addition to friendly URLs, resources that can be moved or be renamed SHOULD expose a URL that contains a unique stable identifier.

除了友好的 URL 以外,能夠移動或重命名的資源也應該暴露一個包含惟一固定標識符的 URL。

PS:通常是暴露主鍵字段,也能夠是其餘惟一的易於理解的字段,好比姓名、標題、郵箱等等。

 

It MAY be necessary to interact with the service to obtain a stable URL from the friendly name for the resource, as in the case of the "/my" shortcut used by some services.

在與 服務 進行交互時可能須要經過友好的名稱來獲取資源固定的 URL,例如某些 服務使用的「/my」快捷方式。

PS:相比/my,我更喜歡/me。

 

The stable identifier is not required to be a GUID.

固定標識符不必定必需得是 GUID。

PS:GUID太長並且不易於理解和閱讀,若是不是必須,儘可能少用此字段。

 

An example of a URL containing a canonical identifier is:

包含規範標識符的 URL 示例(標識符比較友好):

https://api.contoso.com/v1.0/people/7011042402/inbox

 

7.4 Supported methods 支持的方法

Operations MUST use the proper HTTP methods whenever possible, and operation idempotency MUST be respected.

HTTP methods are frequently referred to as the HTTP verbs.

操做必須儘量使用正確的 HTTP 方法,且必須遵照操做冪等

HTTP 方法又一般被稱爲 HTTP 動詞。

PS:

冪等(idempotent、idempotence)是一個數學或計算機學概念,常見於抽象代數中。

冪等有一下幾種定義:

  對於單目運算,若是一個運算對於在範圍內的全部的一個數屢次進行該運算所得的結果和進行一次該運算所得的結果是同樣的,那麼咱們就稱該運算是冪等的。好比絕對值運算就是一個例子,在實數集中,有abs(a)=abs(abs(a))。

  對於雙目運算,則要求當參與運算的兩個值是等值的狀況下,若是知足運算結果與參與運算的兩個值相等,則稱該運算冪等,如求兩個數的最大值的函數,有在在實數集中冪等,即max(x,x) = x。

相信你也沒看懂,其實簡單的來講,冪等的意味着對同一URL的多個請求應該返回一樣的結果。

另外,GET用於信息獲取,POST表示新增,PUT表示修改,DELETE表示刪除。

 

The terms are synonymous in this context, however the HTTP specification uses the term method.

這些術語在此上下文下是同義詞,但 HTTP 規範瞭如何使用這些術語的方法。

 

Below is a list of methods that Microsoft REST services SHOULD support.

下面是 Microsoft REST Service 應該支持的方法列表。

 

Not all resources will support all methods, but all resources using the methods below MUST conform to their usage.

並不是全部資源都支持全部方法,但使用下面方法的全部資源必須聽從下面的用法。

    

 

7.4.1 POST

POST operations SHOULD support the Location response header to specify the location of any created resource that was not explicitly named, via the Location header.

POST 操做應該支持響應頭部信息輸出位置URL,經過響應頭部信息中的Location信息明確已建立資源的URL位置。

PS:大概意思是,建立一個資源時,響應頭部信息應輸出新資源的路徑URL。

 

As an example, imagine a service that allows creation of hosted servers, which will be named by the service:

例如,一個服務容許建立並命名託管服務器:

POST http://api.contoso.com/account1/servers

The response would be something like:

響應將會是這個樣子:

  1. 201 Created

  2. Location:http://api.contoso.com/account1/servers/server321

Where "server321" is the service-allocated server name.

「server321」 是服務建立的託管服務器的名稱。

 

Services MAY also return the full metadata for the created item in the response.

服務也能夠在響應中返回建立項的完整元數據。

 

7.4.2 PATCH

PATCH has been standardized by IETF as the method to be used for updating an existing object incrementally (see [RFC 5789][rfc-5789]).

PATCH 已經被 IETF 標準化,用來對已存在對象(已知資源)進行局部更新。(參考 [RFC 5789][rfc-5789])。

PS:PATCH方法是對PUT的補充,用來對已知資源進行局部更新。

 

Microsoft REST API Guidelines compliant APIs SHOULD support PATCH.

符合 Microsoft REST API 指南的 API 應該支持 PATCH 方法。

 

7.4.3 Creating resources via PATCH (UPSERT semantics) 經過 PATCH 建立資源(UPSERT 定義)

Services that allow callers to specify key values on create SHOULD support UPSERT semantics, and those that do MUST support creating resources using PATCH.

容許調用者在建立資源時指定 key 的服務應該支持 UPSERT ,支持此方法的服務也必須支持經過 PATCH 建立資源。

PS:UPSERT即更新插入,經過PATCH方法,容許指定Key來建立資源,例如經過PATCH方法建立UserId爲88的用戶。

Demo:

curl https://yourInstance.salesforce.com/services/data/v20.0/sobjects/Account/customExtIdField__c/11999 -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @newrecord.json -X PATCH

{

 

    "Name" : "California Wheat Corporation",

    "Type" : "New Customer"

 

}

成功響應:

{

    "id" : "00190000001pPvHAAU",

    "errors" : [ ],

    "success" : true

}

錯誤響應:

{

    "message" : "The requested resource does not exist",

    "errorCode" : "NOT_FOUND"

}

 

Because PUT is defined as a complete replacement of the content, it is dangerous for clients to use PUT to modify data.

由於 PUT 被定義爲徹底替換原數據,因此客戶端直接使用 PUT方法修改數據是很是危險的。

PS:警告:請不要暴露UpdateTime、UpdateBy等字段。。。

 

Clients that do not understand (and hence ignore) properties on a resource are not likely to provide them on a PUT when trying to update a resource, hence such properties could be inadvertently removed.

當對資源屬性不瞭解的客戶端試圖經過 PUT 更新數據時,因爲對屬性不瞭解,極可能忽略了某些屬性,進而致使這些屬性被無心刪除。

PS:好比常見的,客戶端某些字段就是不填致使的業務流程Game Over。

 

Services MAY optionally support PUT to update existing resources, but if they do they MUST use replacement semantics (that is, after the PUT, the resource's properties MUST match what was provided in the request, including deleting any server properties that were not provided).

服務能夠支持 PUT 更新現有資源,但必須是完整替換(也就是說,在 PUT 後,資源的全部屬性必須與請求中提供的內容相匹配,包括刪除全部未提供的服務端屬性)。

 

Under UPSERT semantics, a PATCH call to a nonexistent resource is handled by the server as a "create," and a PATCH call to an existing resource is handled as an "update." To ensure that an update request is not treated as a create or vice-versa, the client MAY specify precondition HTTP headers in the request.

在使用 UPSERT 的狀況下,對不存在資源 使用PATCH 方法時,服務端應進行建立,已存在時,服務端應進行更新處理。爲了確保更新請求不被視爲建立(反之亦然),客戶端能夠在請求中指定預先定義的 HTTP 請求頭。

 

The service MUST NOT treat a PATCH request as an insert if it contains an If-Match header and MUST NOT treat a PATCH request as an update if it contains an If-None-Match header with a value of "*".

若是一個 PATCH 請求包含一個 If-Match 請求頭,那麼服務端毫不能把這個 PATCH 請求當作插入(新增)處理,而且若是它包含一個值爲「*」的 If-None-Match 請求頭,則不能將該 PATCH 請求當作更新處理。

 

If a service does not support UPSERT, then a PATCH call against a resource that does not exist MUST result in an HTTP "409 Conflict" error.

若是服務不支持 UPSERT,那麼對不存在資源的 PATCH 調用必須返回HTTP狀態碼爲 "409 Conflict"的錯誤。

 

7.4.4 Options and link headers

OPTIONS allows a client to retrieve information about a resource, at a minimum by returning the Allow header denoting the valid methods for this resource.

OPTIONS 容許客戶端檢索有關資源的信息,至少能夠返回表示該資源的有效方法的容許的頭部信息。

PS:當發起跨域請求時,瀏覽器會自動發起OPTIONS請求進行檢查。

 

In addition, services SHOULD include a Link header (see [RFC 5988][rfc-5988]) to point to documentation for the resource in question:

此外, 服務應該包括 Link header (參考 [RFC 5988][rfc-5988]) 以指向有關的文檔資源:

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

Where {help} is the URL to a documentation resource.

其中 {help} 是文檔資源的 URL.

PS:例如分頁時,返回下一步、上一步連接信息。這方面,你們能夠參閱Github的API,以下所示:

Link: <https://api.github.com/user/repos?page=3&per_page=100>; rel="next",

  <https://api.github.com/user/repos?page=50&per_page=100>; rel="last"

 

For examples on use of OPTIONS, see [preflighting CORS cross-domain calls][cors-preflight].

有關使用 OPTIONS 的示例,請參考 [preflighting CORS cross-domain calls][cors-preflight]。

 

7.5. Standard request headers 標準請求頭

The table of request headers below SHOULD be used by Microsoft REST API Guidelines services. Using these headers is not mandated, but if used they MUST be used consistently. 
表的請求頭應該遵循微軟REST API服務規範。使用這些標頭不是必須的,可是若是用到,那麼它們必須使用一致。

 

All header values MUST follow the syntax rules set forth in the specification where the header field is defined. Many HTTP headers are defined in RFC7231, however a complete list of approved headers can be found in the IANA Header Registry."

全部頭部值必須遵循在定義頭部字段的規範中所闡述的語法規則(syntax rules )。在HTC721中定義了許多HTTP報頭,可是在IANA報頭註冊表中能夠找到完整的批准報頭列表。

Header| Type |Description 
頭部 | 類型 | 描述 
Authorization| String |Authorization header for the request 
受權 | 字符 | 受權頭部

Date |Date |Timestamp of the request, based on the client's clock, in RFC 5322 date and time format. The server SHOULD NOT make any assumptions about the accuracy of the client's clock. This header MAY be included in the request, but MUST be in this format when supplied. Greenwich Mean Time (GMT) MUST be used as the time zone reference for this header when it is provided. For example: Wed, 24 Aug 2016 18:41:30 GMT. Note that GMT is exactly equal to UTC (Coordinated Universal Time) for this purpose. 
日期 | 日期類型 | 請求時間戳,在RFC 5322日期和時間格式中。服務器不該該信任客戶端時間。該報頭能夠包含在請求中,但在提供時必須以這種格式。當提供該報頭時,必須使用格林尼治平均時間(GMT)做爲時區參考。例如:星期三,2016年8月24日18:41:30 GMT注意到GMT徹底等於UTC(協調的通用時間)。

 

Accept| Content type |The requested content type for the response such as: 
接收 | 內容類型 | 請求響應的請求內容類型,例如application/xml 、text/xml 、application/json 、text/javascript (for JSONP) 

Per the HTTP guidelines, this is just a hint and responses MAY have a different content type, such as a blob fetch where a successful response will just be the blob stream as the payload. For services following OData, the preference order specified in OData SHOULD be followed. 
根據HTTP指南,這只是一個提示,而且響應可能有不一樣的內容類型,例如獲取一個對象,只有返回了對象流纔算是成功的返回。若是服務是OData協議,應該遵循ODATA中指定的優先要求和順序。

 

Accept-Encoding | Gzip, deflate | REST endpoints SHOULD support GZIP and DEFLATE encoding, when applicable. For very large resources, services MAY ignore and return uncompressed data. 
Accept-Encoding  | Gzip, deflate | 在適用時,REST API應支持GZIP和deflate 。對於很是大的資源,服務能夠忽略和返回未壓縮的數據。

PS:Gzip, deflate 是經常使用的HTPP壓縮方式,對於REST API,也是能夠支持HTTP動態壓縮的。不過若是數據量比較大,壓縮會比較消耗CPU資源。因此對於大數據,請慎重。

 

Accept-Language | "en", "es", etc. |Specifies the preferred language for the response. Services are not required to support this, but if a service supports localization it MUST do so through the Accept-Language header. 
Accept-Language | en,es,etc | 指定響應的首選語言。服務不要求必須支持,可是若是服務支持本地化,它必須經過Accept-Language來指定語言。

 

Accept-Charset| Charset type like "UTF-8"| Default is UTF-8, but services SHOULD be able to handle ISO-8859-1. 
Accept-Charset | 字符類型例如UTF-8 | 默認是UTF-8,可是服務應該能處理ISO-8859-1

 

Content-Type| Content type |Mime type of request body (PUT/POST/PATCH) 
Content-Type | 內容類型 | 根據MIME類型的請求對應的主體(put/post/patch)

PS:常見的,咱們經過內容類型application/json 來獲取JSON數據,經過「application/xml」來獲取XML輸出。

 

Prefer | return=minimal, return=representation | If the return=minimal preference is specified, services SHOULD return an empty body in response to a successful insert or update. If return=representation is specified, services SHOULD return the created or updated resource in the response. Services SHOULD support this header if they have scenarios where clients would sometimes benefit from responses, but sometimes the response would impose too much of a hit on bandwidth. 
Prefer  | 返回=極小值 ,返回=表明事物 | 若是指定了返回=最小優先級,則服務應響應成功插入或更新返回空主體。若是指定了Reale=表示,服務應該返回響應中建立的或更新的資源。若是客戶端經過指定返回內容有實際意義或價值,或者有時響應內容過多會對帶寬形成太大的影響,那麼服務就應該支持這個頭部。

PS:經過將Prefer標頭設置能夠省略響應正文。若是Prefer標頭設置爲return-no-content,則服務將使用狀態代碼204(No Content)和響應標頭進行響應。也就是說,建立一個大對象時,客戶端若是指定了Prefer爲return-no-content,服務端能夠返回204而無需返回任何內容,這樣能提供請求速度,節約大量帶寬。

 

If-Match, If-None-Match, If-Range |String |Services that support updates to resources using optimistic concurrency control MUST support the If-Match header to do so. Services MAY also use other headers related to ETags as long as they follow the HTTP specification. 
If-Match, If-None-Match, If-Range  | 字符串| 使用樂觀併發控制支持資源更新的服務必須支持IF匹配頭這樣作。服務也可使用與ETAG相關的其餘頭文件,只要它們遵循HTTP規範。

 

7.6. Standard response headers 標準響應報頭

Services SHOULD return the following response headers, except where noted in the "required" column. 
服務應返回如下響應標題,除非在「必需」欄中註明。

 

Response Header | Required | Description 
響應報頭 | 必填 | 描述

 

Date | All responses | Timestamp the response was processed, based on the server's clock, in RFC 5322 date and time format. This header MUST be included in the response. Greenwich Mean Time (GMT) MUST be used as the time zone reference for this header. For example: Wed, 24 Aug 2016 18:41:30 GMT. Note that GMT is exactly equal to UTC (Coordinated Universal Time) for this purpose. 
日期 | 全部請求| 服務執行時間撮,以RFC 5322的日期和時間格式處理響應。這個頭必須包含在響應中。格林尼治平均時間(GMT)必須用做該報頭的時區參考。例如:星期三,2016年8月24日18:41:30 GMT注意到GMT徹底等於UTC(協調的通用時間)。

 

Content-Type | All responses | The content type 
內容類型 | 全部的請求 | 內容類型

 

Content-Encoding | All responses GZIP or DEFLATE, as appropriate 
Content-Encoding  |全部的請求儘量支持GZIP或DEFLATE,除非特殊狀況

 

Preference-Applied When specified in request Whether a preference indicated in the Prefer request header was applied 
Preference-Applied在請求中指定是否應用了Prefer請求標頭。

 

ETag | When the requested resource has an entity tag | The ETag response-header field provides the current value of the entity tag for the requested variant. Used with If-Match, If-None-Match and If-Range to implement optimistic concurrency control.

ETAG | 當請求的資源具備實體標籤時| ETAG響應頭字段爲所請求的變體提供實體標籤的當前值。與If-Match, If-None-Match、If-Range來實現樂觀併發控制。

 

7.7. Custom headers 自定義選項

Custom headers MUST NOT be required for the basic operation of a given API. 
基本的API操做禁止定義自定義標頭。

 

Some of the guidelines in this document prescribe the use of nonstandard HTTP headers. In addition, some services MAY need to add extra functionality, which is exposed via HTTP headers. The following guidelines help maintain consistency across usage of custom headers. 
本文檔中的一些準則規定了使用非標準HTTP標頭。 此外,某些服務可能須要添加額外的功能,這些功能經過HTTP標頭公開。 如下準則有助於保持自定義標頭使用的一致性。

 

Headers that are not standard HTTP headers MUST have one of two formats: 
不是標準HTTP標頭必須支持如下兩種格式之一: 
1. A generic format for headers that are registered as "provisional" with IANA (RFC 3864) 
用IANA註冊爲「臨時」的標題的通用格式(RFC 3864) 
2. A scoped format for headers that are too usage-specific for registration 
爲註冊使用過特定的頭文件的範圍格式

These two formats are described below. 
下面介紹這兩種格式。

 

7.8. Specifying headers as query parameters 

將頁眉指定爲查詢參數

Some headers pose challenges for some scenarios such as AJAX clients, especially when making cross-domain calls where adding headers MAY not be supported. As such, some headers MAY be accepted as Query Parameters in addition to headers, with the same naming as the header: 
一些標頭可能不兼容一些場景(如Ajax客戶端),尤爲是在跨域調用時,可能不支持添加標頭。所以,除了標頭以外,能夠將一些標頭做爲查詢參數接受,與標頭相同的命名:

 

Not all headers make sense as query parameters, including most standard HTTP headers. 
並不是全部的標頭都是有意義的查詢參數,包括大多數標準的HTTP頭。

 

The criteria for considering when to accept headers as parameters are: 
考慮什麼時候接受標頭做爲參數的標準是: 
1. Any custom headers MUST be also accepted as parameters. 
任何自定義標頭也必須做爲參數接受。 
2. Required standard headers MAY be accepted as parameters. 
請求的標準標頭也能夠做爲參數接受。 
3. Required headers with security sensitivity (e.g., Authorization header) MIGHT NOT be appropriate as parameters; the service owner SHOULD evaluate these on a case-by-case basis. 
具備安全敏感性的必填標頭(例如,受權標頭)可能不適合做爲參數;服務全部者應該根據具體狀況具體分析。

 

The one exception to this rule is the Accept header. It's common practice to use a scheme with simple names instead of the full functionality described in the HTTP specification for Accept.

這個規則的一個例外是Accept標頭。一般使用具備簡單名稱的方案,而不是使用HTTP規範中描述的Accept的完整功能。

 

7.9. PII parameters PII(我的可識別信息)參數

Consistent with their organization's privacy policy, clients SHOULD NOT transmit personally identifiable information (PII) parameters in the URL (as part of path or query string) because this information can be inadvertently exposed via client, network, and server logs and other mechanisms. 
與其組織的隱私策略一致,客戶端不該該在URL中發送我的可識別信息(PII)參數(做爲路徑或查詢字符串的一部分),由於能夠經過客戶端、網絡和服務器日誌和其餘機制不經意地公開該信息。

PS:PII——我的可標識信息。好比家庭地址,身份證信息。

 

Consequently, a service SHOULD accept PII parameters transmitted as headers. 
所以,一個服務應該接受PII參數做爲頭部參數傳輸。

 

However, there are many scenarios where the above recommendations cannot be followed due to client or software limitations. To address these limitations, services SHOULD also accept these PII parameters as part of the URL consistent with the rest of these guidelines. 
然而,因爲客戶端或軟件限制,有許多狀況下沒法遵循上述建議。爲了解決這些限制,服務還應該接受這些PII參數做爲URL的一部分,並與這些指南的其他部分保持一致。

 

Services that accept PII parameters -- whether in the URL or as headers -- SHOULD be compliant with privacy policy specified by their organization's engineering leadership. This will typically include recommending that clients prefer headers for transmission and implementations adhere to special precautions to ensure that logs and other service data collection are properly handled. 
接受PII參數的服務——不管是在URL中仍是做爲頭部——應該符合由其組織的領導層指定的隱私策略。這一般包括推薦的客戶端傳輸的標頭,而且實現遵循特殊的預防措施,以確保正確處理日誌和其餘服務數據的收集。

 

7.10. Response formats 響應格式

For organizations to have a successful platform, they must serve data in formats developers are accustomed to using, and in consistent ways that allow developers to handle responses with common code. 
一個成功的平臺,必須以開發人員習慣使用的格式以及容許開發人員使用公共Http代碼處理響應。

 

Web-based communication, especially when a mobile or other low-bandwidth client is involved, has moved quickly in the direction of JSON for a variety of reasons, including its tendency to be lighter weight and its ease of consumption with JavaScript-based clients. 
基於Web的通訊,特別是當涉及移動或其餘低帶寬客戶機時,因爲各類緣由,已經迅速向JSON格式方向發展,主要是因爲其更輕量以及易於與JavaScript交互。

 

JSON property names SHOULD be camelCased. 
JSON屬性名稱應該符合CAMELCASE命名規範。

 

Services SHOULD provide JSON as the default encoding. 
服務應該提供JSON格式做爲默認輸出格式。

 

7.10.1. Clients-specified response format 

客戶端指定響應格式

In HTTP, response format SHOULD be requested by the client using the Accept header. This is a hint, and the server MAY ignore it if it chooses to, even if this isn't typical of well-behaved servers. Clients MAY send multiple Accept headers and the service MAY choose one of them. 
在HTTP中,客戶端應該使用Accept標頭請求響應格式。 服務端能夠選擇性的忽略,即便這不是典型的良好的服務。 客戶端能夠發送多個Accept標頭,服務能夠選擇其中一個格式進行返回。

 

The default response format (no Accept header provided) SHOULD be application/json, and all services MUST support application/json. 
默認的響應格式(沒有提供Accept報頭)應該是application/json,而且全部服務必須支持application/json。

 

Accept Header | Response type | Notes 
接受標頭 | 響應類型 | 備註


application/json| Payload SHOULD be returned as JSON | Also accept text/javascript for JSONP cases 
application/json | 必須是返回json格式 | 一樣接受JSONP請求的text/JavaScript

GET https://api.contoso.com/v1.0/products/user 
Accept: application/json

 

7.10.2. Error condition responses 錯誤的條件響應

For nonsuccess conditions, developers SHOULD be able to write one piece of code that handles errors consistently across different Microsoft REST API Guidelines services. This allows building of simple and reliable infrastructure to handle exceptions as a separate flow from successful responses. The following is based on the OData v4 JSON spec. However, it is very generic and does not require specific OData constructs. APIs SHOULD use this format even if they are not using other OData constructs. 
對於非成功條件,開發人員應該可以編寫一段代碼進行處理,以在不一樣的Microsoft REST API準則服務中一致地處理相似錯誤。 這容許構建簡單可靠的基礎架構來處理異常,做爲成功響應的獨立的處理流程。 如下是基於OData v4 JSON規範。 可是,它是很是通用的,不須要指定特定的OData結構。 API應該使用這種格式,即便它們沒有使用其餘OData結構。

 

The error response MUST be a single JSON object. This object MUST have a name/value pair named "error." The value MUST be a JSON object. 
錯誤響應必須是單個JSON對象。此對象必須有名爲「錯誤」的鍵值對,該值必須是JSON對象。

 

This object MUST contain name/value pairs with the names "code" and "message," and it MAY contain name/value pairs with the names "target," "details" and "innererror." 
這個對象必須包含名稱爲「code」和「message」的鍵值對,它可能包含名稱爲「target」、「.」和「innererror」的鍵值對。

 

The value for the "code" name/value pair is a language-independent string. Its value is a service-defined error code that SHOULD be human-readable. This code serves as a more specific indicator of the error than the HTTP error code specified in the response. Services SHOULD have a relatively small number (about 20) of possible values for "code," and all clients MUST be capable of handling all of them. Most services will require a much larger number of more specific error codes, which are not interesting to all clients. These error codes SHOULD be exposed in the "innererror" name/value pair as described below. Introducing a new value for "code" that is visible to existing clients is a breaking change and requires a version increase. Services can avoid breaking changes by adding new error codes to "innererror" instead. 
「code」的值是與語言無關的字符串。它的值是該服務定義的錯誤代碼,應該是人類可讀的易於理解的。與響應中指定的HTTP錯誤代碼相比,此代碼用做錯誤的更具體的指示。服務應該有一個相對小的數量(約20)錯誤碼可能的範圍值,「全部客戶端必須可以處理全部的錯誤碼。大多數服務將須要更大數量的更具體的錯誤代碼以知足全部的客戶端請求。這些錯誤代碼應在「內部錯誤」中公開,以下所述。爲現有客戶端可見的「代碼」引入新值是一個突破性的改變,須要增長版本。服務能夠經過向「內部錯誤」添加新的錯誤代碼來避免破壞更改。

 

The value for the "message" name/value pair MUST be a human-readable representation of the error. It is intended as an aid to developers and is not suitable for exposure to end users. Services wanting to expose a suitable message for end users MUST do so through an annotation or custom property. Services SHOULD NOT localize "message" for the end user, because doing so might make the value unreadable to the app developer who may be logging the value, as well as make the value less searchable on the Internet. 
「消息」鍵值對的值必須是錯誤提示消息,必須是可讀且易於理解。它的目的是幫助開發人員,不適合暴露給最終用戶。但願爲最終用戶公開合適消息的服務必須經過註釋或自定義屬性進行。服務不該該爲最終用戶本地化「消息」,由於這樣作可能使值對於可能正在記錄值的應用程序開發人員不可讀,而且使值在因特網上可搜索性下降。

 

The value for the "target" name/value pair is the target of the particular error (e.g., the name of the property in error). 
「目標」鍵值對的值是特定錯誤的目標(例如,錯誤的屬性名稱)。

 

The value for the "details" name/value pair MUST be an array of JSON objects that MUST contain name/value pairs for "code" and "message," and MAY contain a name/value pair for "target," as described above. The objects in the "details" array usually represent distinct, related errors that occurred during the request. See example below. 
「.」名稱/值對的值必須是JSON對象的數組,該數組必須包含「code」和「message」的名稱/值對,而且容許包含「target」的名稱/值對,如上所述。「細節」數組中的對象一般表示在請求期間發生的不一樣的、相關的錯誤。見下面的例子。

 

The value for the "innererror" name/value pair MUST be an object. The contents of this object are service-defined. Services wanting to return more specific errors than the root-level code MUST do so by including a name/value pair for "code" and a nested "innererror." Each nested "innererror" object represents a higher level of detail than its parent. When evaluating errors, clients MUST traverse through all of the nested "innererrors" and choose the deepest one that they understand. This scheme allows services to introduce new error codes anywhere in the hierarchy without breaking backwards compatibility, so long as old error codes still appear. The service MAY return different levels of depth and detail to different callers. For example, in development environments, the deepest "innererror" MAY contain internal information that can help debug the service. To guard against potential security concerns around information disclosure, services SHOULD take care not to expose too much detail unintentionally. Error objects MAY also include custom server-defined name/value pairs that MAY be specific to the code. Error types with custom server-defined properties SHOULD be declared in the service's metadata document. See example below. 
「內部錯誤」名稱/值對的值必須是一個對象。這個對象的內容是服務定義的。但願返回比根級代碼更具體的錯誤的服務必須經過包括「code」的名稱/值對和嵌套的「innererror」來返回。在評估錯誤時,客戶機必須遍歷全部嵌套的「內部錯誤」,並選擇他們理解的最深的一個。該方案容許服務在層次結構中的任何地方引入新的錯誤代碼,而不破壞向後兼容性,只要仍然出現舊的錯誤代碼。服務能夠返回不一樣級別的深度和細節給不一樣的呼叫者。例如,在開發環境中,最深的「innererror」可能包含能夠幫助調試服務的內部信息。爲了防止圍繞信息公開的潛在安全隱患,服務應該注意不要無心中暴露太多的細節。錯誤對象還能夠包括特定於代碼的自定義服務器定義的名稱/值對。自定義服務器定義屬性的錯誤類型應該在服務的元數據文檔中聲明。見下面的例子。

 

Error responses MAY contain annotations in any of their JSON objects. 
錯誤的請求可能包含他們的json對象的任何註釋。

 

We recommend that for any transient errors that may be retried, services SHOULD include a Retry-After HTTP header indicating the minimum number of seconds that clients SHOULD wait before attempting the operation again. 
咱們建議,能夠重試任何瞬態偏差,服務應該包括重試HTTP標頭指示秒的最低數量,客戶應該在試圖再次操做的等待後。

 

ErrorResponse : Object 錯誤的請求:對象

Property |Type |Required |Description 
特性 |類型 | 必填 | 描述 
error |Error | ✔ |The error object. 
錯誤 |錯誤 | 正確 | 錯誤的對象

 

Error : Object 錯誤的對象

Property | Type |Required |Description 
特性 | 類型 | 必填 | 描述 
code | String (enumerated) ✔ |One of a server-defined set of error codes. 
代碼 | 字符(列舉)| |服務器定義的錯誤代碼集之一。 
message String ✔ A human-readable representation of the error. 
消息| 字符| |錯誤的人類可讀表示。 
target String The target of the error. 
目標 | 字符 | 偏差的目標。 
details Error[] An array of details about specific errors that led to this reported error. 
詳情 |錯誤| 有關致使此報告錯誤的特定錯誤的詳細信息的數組 
innererror InnerError An object containing more specific information than the current object about the error. 
內部錯誤 |內部錯誤 |一個對象,包含比當前對象更具體的有關錯誤的信息。

 

InnerError : Object 內部錯誤:對象 
Property | Type |Required | Description 
特性 | 類型 | 必填 | 描述 
code |String | A more specific error code than was provided by the containing error. 
代碼 | 字符 | 一個比包含錯誤提供的更具體的錯誤代碼。 
innererror | InnerError | An object containing more specific information than the current object about the error. 
內部錯誤 | 內部錯誤 | 包含與當前對象有關錯誤的更具體信息的對象

 

Examples 例如 
Example of "innererror":


"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" 




}

In this example, the most basic error code is "BadArgument," but for clients that are interested, there are more specific error codes in "innererror." The "PasswordReuseNotAllowed" code may have been added by the service at a later date, having previously only returned "PasswordDoesNotMeetPolicy." Existing clients do not break when the new error code is added, but new clients MAY take advantage of it. The "PasswordDoesNotMeetPolicy" error also includes additional name/value pairs that allow the client to determine the server's configuration, validate the user's input programmatically, or present the server's constraints to the user within the client's own localized messaging. 
在這個示例中,最基本的錯誤代碼是「BadArgument」,但對於客戶端,在「innererror」中有更多的特定錯誤代碼。服務可能在稍後的日期添加了「PasswordReuseNotAllo.」代碼,以前只返回了「PasswordDoesNotMeetPolicy」。現有客戶端在添加新錯誤代碼時不會中斷,但新客戶端能夠利用它。「PasswordDoesNotMeetPolicy」錯誤還包括額外的名稱/值對,這些名稱/值對容許客戶端肯定服務器的配置、以編程方式驗證用戶的輸入、或在客戶端本身的本地化消息傳遞中向用戶呈現服務器的約束。

 

Example of "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" 



}

 

In this example there were multiple problems with the request, with each individual error listed in "details." 
在這個示例中,請求存在多個問題,每一個細節錯誤都在「details」中列出。

 

7.11. HTTP Status Codes 請求狀態代碼

Standard HTTP Status Codes SHOULD be used; see the HTTP Status Code definitions for more information. 
應該使用標準的HTTP狀態代碼;有關更多信息,請參見HTTP狀態代碼定義。

 

7.12. Client library optional 客戶端庫可選

Developers MUST be able to develop on a wide variety of platforms and languages, such as Windows, macOS, Linux, C#, Python, Node.js, and Ruby. 
開發人員必須可以在各類平臺和語言上進行開發,好比Windows、macOS、Linux、C#、Python、Node.js和Ruby。

 

Services SHOULD be able to be accessed from simple HTTP tools such as curl without significant effort. 
服務應該可以從簡單的HTTP工具(如curl)訪問,而不須要付出很大的努力。

 

Service developer portals SHOULD provide the equivalent of "Get Developer Token" to facilitate experimentation and curl support. 開發者中心應該提供相似「得到開發者令牌」的支持,以便開發者聯調和使用CURL測試。

相關文章
相關標籤/搜索