<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          OpenAPI 標(biāo)準(zhǔn)規(guī)范,了解一下?

          共 11000字,需瀏覽 22分鐘

           ·

          2021-08-05 03:43


          什么是API規(guī)范

          API 是模塊或者子系統(tǒng)之間交互的接口定義。好的系統(tǒng)架構(gòu)離不開(kāi)好的 API 設(shè)計(jì),而一個(gè)設(shè)計(jì)不夠完善的 API 則注定會(huì)導(dǎo)致系統(tǒng)的后續(xù)發(fā)展和維護(hù)非常困難。在關(guān)鍵環(huán)節(jié)制定明確的API規(guī)范有助于 Service 對(duì)內(nèi)提高產(chǎn)品間互通的效率,對(duì)外提供一致的使用體驗(yàn),也有助于更好地被集成。

          對(duì)于API規(guī)范,比較知名的是 OpenAPI Specfication[1]Google API Design Guide[2]。前者針對(duì) RESTful API 設(shè)計(jì)在細(xì)節(jié)層面給出了非常具體的規(guī)定,已經(jīng)成為 RESTful API 設(shè)計(jì)領(lǐng)域的事實(shí)標(biāo)準(zhǔn),而后者則主要從云廠(chǎng)商的角度提出許多最佳實(shí)踐性質(zhì)的規(guī)范與建議,這些原則不僅僅適用于 RESTful API,也適合其他類(lèi)型API設(shè)計(jì)。

          雖然RESTful設(shè)計(jì)風(fēng)格曝光率很高,但并不是所有云服務(wù)商都選擇了完全遵循RESTful,例如AWS和 阿里云[3] RPC 風(fēng)格反而占了大多數(shù),Google和Azure則RESTful居多。

          RESTful API的優(yōu)勢(shì)是HTTP具備更好的易用性,讓異構(gòu)系統(tǒng)更容易集成,且開(kāi)發(fā)執(zhí)行效率比較高,面向資源要求也比較高。而RPC API可以使用更廣泛的框架和方案,技術(shù)層面更底層也更為靈活,設(shè)計(jì)起來(lái)相對(duì)簡(jiǎn)單,掌握起來(lái)有一定門(mén)檻,架構(gòu)上更加復(fù)雜。RESTful 與 RPC 模式對(duì)比如下:


          RESTful APIRPC API
          是否有統(tǒng)一規(guī)范HTTP無(wú)
          面向資源不確定
          性能
          通用性
          復(fù)雜度

          如果強(qiáng)制統(tǒng)一風(fēng)格,有些適合 RESTful 風(fēng)格的服務(wù)非要使用RPC的話(huà),看起來(lái)就會(huì)比較丑陋,如果只是一個(gè)過(guò)程化的服務(wù)調(diào)用,往 RESTful 資源化設(shè)計(jì)方向去靠會(huì)比較困難。但如果不強(qiáng)制使用統(tǒng)一風(fēng)格,會(huì)造成針對(duì)API的體系化支持會(huì)更加復(fù)雜,例如為兼容兩種風(fēng)格SDK的自動(dòng)化支持需要兩套代碼。

          選擇API風(fēng)格時(shí)要考慮幾個(gè)問(wèn)題:

          • 選擇支持哪種風(fēng)格,才能更好地體現(xiàn)業(yè)務(wù)特性,讓客戶(hù)操作起來(lái)更加方便;
          • 設(shè)計(jì)API時(shí)能否面向資源設(shè)計(jì),相應(yīng)的工程人員是否具備做這種設(shè)計(jì)的能力;
          • 針對(duì)這種風(fēng)格工具鏈的支持是否到位,投入產(chǎn)出比如何;
          • 業(yè)界流行的趨勢(shì)如何,是否需要考慮與其他系統(tǒng)體系的互操作。

          用戶(hù)使用API來(lái)訪(fǎng)問(wèn) Service,本質(zhì)上是想通過(guò)對(duì)某種資源執(zhí)行特定的操作來(lái)完成一個(gè)業(yè)務(wù)動(dòng)作。對(duì)于資源有兩個(gè)關(guān)鍵點(diǎn):一是要有統(tǒng)一的資源模型;二是要明確資源關(guān)系。統(tǒng)一的資源模型對(duì) Service 的幫助是巨大的:

          • 它可以使API具有更清晰的結(jié)構(gòu),幫助用戶(hù)理解;
          • 它可以幫助對(duì)比API與后臺(tái)實(shí)體關(guān)系模型,更容易提供更完整的API服務(wù);
          • 它可以使產(chǎn)品協(xié)作更加順暢,對(duì)資源的操作也更加規(guī)范化;
          • 它可以使云服務(wù)底層平臺(tái)實(shí)現(xiàn)起來(lái)更統(tǒng)一、更方便;
          • 它可以使圍繞API的生態(tài)集成起來(lái)更加簡(jiǎn)單、高效。

          確定了設(shè)計(jì)模式和資源模型后,就需要考慮 API的設(shè)計(jì)細(xì)節(jié)了,諸如API名稱(chēng)、參數(shù)名、屬性名稱(chēng)、數(shù)據(jù)格式、錯(cuò)誤碼之類(lèi)的信息。除此之外,還要考慮以下一些問(wèn)題:

          • 在API命名的時(shí)候,遵循什么樣的范式來(lái)確保大體風(fēng)格相似?動(dòng)詞、名詞、介詞如何組合才能保持API風(fēng)格看起來(lái)比較統(tǒng)一,降低理解成本?
          • 對(duì)于類(lèi)似的操作,有沒(méi)有使用規(guī)范?有哪些公共的標(biāo)準(zhǔn)詞匯使得同類(lèi)型的操作可以比較容易理解,避免使用晦澀奇怪的詞匯(例如讀操作,Read/Query/Describe/List/Get中都在什么場(chǎng)合使用什么動(dòng)詞)?
          • 被廣泛使用的參數(shù)如何盡可能保持一致,避免不同產(chǎn)品的表達(dá)混亂的情況(例如分頁(yè)參數(shù)用PageNumber還是PageNum)?
          • 對(duì)于常用的場(chǎng)景,例如冪等、分頁(yè)、異步API的設(shè)計(jì)有沒(méi)有統(tǒng)一的規(guī)范,避免使用體驗(yàn)不一致?
          • 錯(cuò)誤碼應(yīng)該怎么設(shè)計(jì)?公共錯(cuò)誤碼怎么統(tǒng)一,業(yè)務(wù)錯(cuò)誤碼怎么表達(dá)?

          上述問(wèn)題都是實(shí)際研發(fā)過(guò)程中要注意的,要全部羅列的話(huà)遠(yuǎn)不止這些。API的用詞描述是 Service 展現(xiàn)給外部用戶(hù)的第一印象,絕非隨意寫(xiě)就。對(duì)人員有一定規(guī)模,內(nèi)部有多條產(chǎn)品線(xiàn)的組織來(lái)說(shuō),如何協(xié)調(diào)組織的各個(gè)部分對(duì)外具有統(tǒng)一的體驗(yàn)是個(gè)很大挑戰(zhàn)。

          Service 在管理API時(shí)應(yīng)該考慮一些具體的規(guī)范,對(duì)命名規(guī)則、標(biāo)準(zhǔn)詞匯、最佳實(shí)踐模式、錯(cuò)誤碼等信息都有明確的規(guī)定,同時(shí)用系統(tǒng)化、平臺(tái)化的手段來(lái)管理API,確保不走偏。設(shè)計(jì)風(fēng)格不是云服務(wù)API設(shè)計(jì)中致命的問(wèn)題,但是它關(guān)乎云服務(wù)外表形象,不可不察。

          API是后端服務(wù)的外部表達(dá),是服務(wù)就有可能出現(xiàn)問(wèn)題,無(wú)論這個(gè)問(wèn)題是可預(yù)期的還是不可預(yù)期的。如果只考慮功能本身功能特性,而忽視對(duì)異常情況的設(shè)計(jì),當(dāng)問(wèn)題出現(xiàn)的時(shí)候業(yè)務(wù)本身可能無(wú)法感知造成服務(wù)異常,更重要的是站在客戶(hù)角度去看,不能有效獲取錯(cuò)誤原因是非常痛苦的,很多時(shí)候只能束手無(wú)策,降低云服務(wù)提供商的整體口碑,甚至損害營(yíng)收。

          OpenAPI規(guī)范

          本規(guī)范基于 RESTful 風(fēng)格的架構(gòu)設(shè)計(jì)準(zhǔn)則,廣泛參考 GitHub、Azure、Google API Design Guide、騰訊云、阿里云等公開(kāi)資料,兼顧現(xiàn)有實(shí)際情況和未來(lái)發(fā)展做一個(gè)概括性記錄總結(jié)。

          一、協(xié)議

          API 與用戶(hù)的通信協(xié)議,總是使用 HTTPS 協(xié)議。這個(gè)和 RESTful API 本身沒(méi)有很大的關(guān)系,但是對(duì)于增加網(wǎng)站的安全是非常重要的。特別如果你提供的是公開(kāi) API,用戶(hù)的信息泄露或者被攻擊會(huì)嚴(yán)重影響網(wǎng)站的信譽(yù)。

          二、版本(Version)

          關(guān)于版本的設(shè)計(jì)有3種形式:

          1. 將 API 的版本號(hào)放入 URL 中,如:http://api.example.com/v1,這樣方便和直觀;

          2. 將版本號(hào)記錄在 url query中,如:http://api.example.com?param1=val&version=1.0中的 version 參數(shù)。

          3. 將版本號(hào)放在 HTTP 頭信息中,基于的準(zhǔn)則是:不同的版本,可以理解成同一種資源的不同形式,所以應(yīng)該采用同一個(gè)URL。如:Accept: application/json; version=1.0,可以參考Github API Design[4]Versioning REST Services[5];

          根據(jù)現(xiàn)有的實(shí)際情況,如果是為了兼容已存在的服務(wù)接口,可以采用對(duì)應(yīng)的形式。如果是新構(gòu)建的體系結(jié)構(gòu),建議采用第三種。

          三、Schema

          URI的格式定義如下:URI = scheme "://" authority "/" path \[ "?" query \] \[ "#" fragment \]

          URL 是 URI 的一個(gè)子集(一種具體實(shí)現(xiàn)),對(duì)于 REST API 來(lái)說(shuō)一個(gè)資源一般對(duì)應(yīng)一個(gè)唯一的 URI(URL)。在 URL 的設(shè)計(jì)中,我們會(huì)遵循一些規(guī)則,使接口看起透明易讀,方便使用者調(diào)用。

          "/"分隔符一般用來(lái)對(duì)資源層級(jí)的劃分。對(duì)于 RESTful API 來(lái)說(shuō),"/"只是一個(gè)分隔符,并無(wú)其他含義。為了避免混淆,"/"不應(yīng)該出現(xiàn)在URL的末尾。

          URL 中盡量使用連字符"-"代替下劃線(xiàn)"_"的使用。 連字符"-"一般用來(lái)分割 URL 中出現(xiàn)的字符串(單詞),來(lái)提高 URL 的可讀性,例如:http://api.example.restapi.org/blogs/mark-masse/entries/this-is-my-first-post。使用下劃線(xiàn)"_"來(lái)分割字符串(單詞)可能會(huì)和鏈接的樣式?jīng)_突重疊,而影響閱讀性。但實(shí)際上,"-"和"_"對(duì)URL 中字符串的分割語(yǔ)意上還是有些差異的:"-"分割的字符串(單詞)一般各自都具有獨(dú)立的含義,可參見(jiàn)上面的例子。而"_"一般用于對(duì)一個(gè)整體含義的字符串做了層級(jí)的分割,方便閱讀,例如你想在 URL 中體現(xiàn)一個(gè) IP 地址的信息:210_110_25_88 . (歡迎關(guān)注:朱小廝的博客)

          URL應(yīng)該統(tǒng)一使用小寫(xiě)字母。

          URL中不要包含文件(腳本)的擴(kuò)展名。例如 .json 之內(nèi)的就不要出現(xiàn)了,對(duì)于接口來(lái)說(shuō)沒(méi)有任何實(shí)際的意義。如果是想對(duì)返回的數(shù)據(jù)內(nèi)容格式標(biāo)示的話(huà),通過(guò) HTTP Header 中的 Content-Type 字段更好一些。

          對(duì)于響應(yīng)返回的格式,JSON 因?yàn)樗目勺x性、緊湊性以及多種語(yǔ)言支持等優(yōu)點(diǎn),成為了 HTTP API 最常用的返回格式。因此,最好采用 JSON 作為返回內(nèi)容的格式。如果用戶(hù)需要其他格式,比如 xml,應(yīng)該在請(qǐng)求頭部 Accept 中指定。對(duì)于不支持的格式,服務(wù)端需要返回正確的 status code,并給出詳細(xì)的說(shuō)明。

          JSON中的所有字段都應(yīng)該用小寫(xiě)的蛇形命名形式,而不是采用駝峰命名。

          四、以資源為中心的 URL 設(shè)計(jì)

          資源是 Restful API 的核心元素,所有的操作都是針對(duì)特定資源進(jìn)行的。而資源就是 URL(Uniform Resoure Locator)表示的,所以簡(jiǎn)潔、清晰、結(jié)構(gòu)化的 URL 設(shè)計(jì)是至關(guān)重要的。Github 可以說(shuō)是這方面的典范,下面我們就拿 repository 來(lái)說(shuō)明:

          /users/:username/repos
          /users/:org/repos
          /repos/:owner/:repo
          /repos/:owner/:repo/tags
          /repos/:owner/:repo/branches/:branch

          我們可以看到幾個(gè)特性:

          • 資源分為單個(gè)文檔和集合,盡量使用復(fù)數(shù)來(lái)表示資源,單個(gè)資源通過(guò)添加 id 或者 name 等來(lái)表示
          • 一個(gè)資源可以有多個(gè)不同的 URL
          • 資源可以嵌套,通過(guò)類(lèi)似目錄路徑的方式來(lái)表示,以體現(xiàn)它們之間的關(guān)系

          最常見(jiàn)的一種設(shè)計(jì)錯(cuò)誤,就是URL包含動(dòng)詞。 因?yàn)?資源"表示一種實(shí)體,所以應(yīng)該是名詞,URL 不應(yīng)該有動(dòng)詞,動(dòng)詞應(yīng)該放在 HTTP Method (參考下一條)中。舉例來(lái)說(shuō),某個(gè) URL 是 /users/show/1,其中 show是動(dòng)詞,這個(gè) URL 就設(shè)計(jì)錯(cuò)了,正確的寫(xiě)法應(yīng)該是 /users/1,然后用 HTTP GET 方法表示 show。

          如果某些動(dòng)作是HTTP 動(dòng)詞表示不了的,你可以把動(dòng)作看成是一種資源。比如網(wǎng)上匯款,從賬戶(hù)1向賬戶(hù)2匯款500元,錯(cuò)誤的 URL 是:

          POST /accounts/1/transfer/500/to/2

          正確的寫(xiě)法是把動(dòng)詞 transfer 改成transaction,資源不能是動(dòng)詞,但是可以是一種服務(wù):

          POST  /transactoin HTTP/1.1
          HOST: 127.0.0.1

          from=1&to=2&amount=500

          五、正確使用 HTTP Method

          有了資源的 URI 設(shè)計(jì),所有針對(duì)資源的操作都是使用 HTTP 方法指定的。比較常用的 HTTP/1.1 動(dòng)詞有下面5個(gè):

          • GET:從服務(wù)器取出資源(一項(xiàng)或多項(xiàng))。
          • POST:在服務(wù)器新建一個(gè)資源。
          • PUT:在服務(wù)器更新資源(客戶(hù)端提供改變后的完整資源)。
          • PATCH:在服務(wù)器更新資源(更新資源的部分屬性)。
          • DELETE:從服務(wù)器刪除資源。

          還有4個(gè)不常用的 HTTP/1.1 動(dòng)詞:

          • HEAD:只獲取某個(gè)資源的頭部信息。比如只想了解某個(gè)文件的大小,某個(gè)資源的修改日期等
          • OPTIONS:獲取信息,關(guān)于資源的哪些屬性是客戶(hù)端可以改變的。
          • TRACE:追蹤路徑。不建議使用。
          • CONNECT:要求用隧道協(xié)議連接代理。不建議使用。

          舉例:

          GET /repos/:owner/:repo/issues
          GET /repos/:owner/:repo/issues/:number
          POST /repos/:owner/:repo/issues
          PATCH /repos/:owner/:repo/issues/:number
          DELETE /repos/:owner/:repo

          這里順帶探討一下,HTTP 協(xié)議涉及到的一種重要性質(zhì):冪等性(Idempotence)。在 HTTP/1.1 規(guī)范中冪等性的定義是:

          Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

          從定義上看,HTTP 方法的冪等性是指一次和多次請(qǐng)求某一個(gè)資源應(yīng)該具有同樣的副作用。冪等性屬于語(yǔ)義范疇,正如編譯器只能幫助檢查語(yǔ)法錯(cuò)誤一樣,HTTP 規(guī)范也沒(méi)有辦法通過(guò)消息格式等語(yǔ)法手段來(lái)定義它,這可能是它不太受到重視的原因之一。但實(shí)際上,冪等性是分布式系統(tǒng)設(shè)計(jì)中十分重要的概念,而 HTTP 的分布式本質(zhì)也決定了它在 HTTP 中具有重要地位。

          安全方法是指不修改資源的 HTTP 方法。譬如,當(dāng)使用 GET 或者 HEAD 作為資源 URL,都必須不去改變資源。然而,這并不全準(zhǔn)確。意思是:它不改變資源的表示形式。對(duì)于安全方法,它仍然可能改變服務(wù)器上的內(nèi)容或資源,但這必須不導(dǎo)致不同的表現(xiàn)形式。


          HTTP Method
          冪等
          安全
          1
          OPTIONS
          yes
          yes
          2
          GET
          yes
          yes
          3
          HEAD
          yes
          yes
          4
          PUT
          yes
          no
          5
          POST
          no
          no
          6
          DELETE
          yes
          no
          7
          PATCH
          no
          no

          實(shí)際上接口的冪等或者安全與否取決于接口的實(shí)現(xiàn),只是 HTTP Method 語(yǔ)義上我們約定俗成地認(rèn)為實(shí)現(xiàn)的過(guò)程會(huì)參照上表所示。對(duì)于冪等的接口,客戶(hù)端就可以放心地多次調(diào)用,網(wǎng)關(guān)層面也可以重試。

          六、狀態(tài)碼 (Status Code)

          HTTP 應(yīng)答中,需要帶一個(gè)很重要的字段:status code。它說(shuō)明了請(qǐng)求的大致情況,是否正常完成、需要進(jìn)一步處理、出現(xiàn)了什么錯(cuò)誤,對(duì)于客戶(hù)端非常重要。狀態(tài)碼都是三位的整數(shù),大概分成了幾個(gè)區(qū)間:

          • 2XX:請(qǐng)求正常處理并返回
          • 3XX:重定向,請(qǐng)求的資源位置發(fā)生變化
          • 4XX:客戶(hù)端發(fā)送的請(qǐng)求有錯(cuò)誤
          • 5XX:服務(wù)器端錯(cuò)誤

          在 HTTP API 設(shè)計(jì)中,經(jīng)常用到的狀態(tài)碼以及它們的意義如下表:

          Status Code
          語(yǔ)義
          說(shuō)明
          200
          OK
          請(qǐng)求已成功
          201
          Created
          請(qǐng)求已完成,并導(dǎo)致了一個(gè)或者多個(gè)資源被創(chuàng)建,最常用在 POST 創(chuàng)建資源的時(shí)候
          202
          Accepted
          請(qǐng)求已經(jīng)接收并開(kāi)始處理,但是處理還沒(méi)有完成。一般用在異步處理的情況,響應(yīng) body 中應(yīng)該告訴客戶(hù)端去哪里查看任務(wù)的狀態(tài)
          204
          No Content
          請(qǐng)求已經(jīng)處理完成,但是沒(méi)有信息要返回,經(jīng)常用在 PUT 更新資源的時(shí)候(客戶(hù)端提供資源的所有屬性,因此不需要服務(wù)端返回)。如果有重要的 metadata,可以放到頭部返回
          301
          Moved Permanently
          請(qǐng)求的資源已經(jīng)永久性地移動(dòng)到另外一個(gè)地方,后續(xù)所有的請(qǐng)求都應(yīng)該直接訪(fǎng)問(wèn)新地址。服務(wù)端會(huì)把新地址寫(xiě)在 Location 頭部字段,方便客戶(hù)端使用。允許客戶(hù)端把 POST 請(qǐng)求修改為 GET。
          302
          Moved Temporarily
          臨時(shí)重定向
          304
          Not Modified
          請(qǐng)求的資源和之前的版本一樣,沒(méi)有發(fā)生改變。用來(lái)緩存資源,和條件性請(qǐng)求(conditional request)一起出現(xiàn)
          307
          Temporary Redirect
          目標(biāo)資源暫時(shí)性地移動(dòng)到新的地址,客戶(hù)端需要去新地址進(jìn)行操作,但是 不能 修改請(qǐng)求的方法。
          308
          Permanent Redirect
          和 301 類(lèi)似,除了客戶(hù)端 不能 修改原請(qǐng)求的方法
          400
          Bad Request
          1.語(yǔ)義有誤,當(dāng)前請(qǐng)求無(wú)法被服務(wù)器理解; 2. 請(qǐng)求參數(shù)有誤。
          401
          Unauthorized
          當(dāng)前請(qǐng)求需要身份驗(yàn)證。
          403
          Forbidden
          服務(wù)器已經(jīng)理解請(qǐng)求,但是拒絕執(zhí)行它。與401響應(yīng)不同的是,身份驗(yàn)證并不能提供任何幫助,而且這個(gè)請(qǐng)求也不應(yīng)該被重復(fù)提交。如果這不是一個(gè) HEAD 請(qǐng)求,而且服務(wù)器希望能夠講清楚為何請(qǐng)求不能被執(zhí)行,那么就應(yīng)該在實(shí)體內(nèi)描述拒絕的原因。當(dāng)然服務(wù)器也可以返回一個(gè)404響應(yīng),假如它不希望讓客戶(hù)端獲得任何信息。
          404
          Not Found
          請(qǐng)求失敗,請(qǐng)求所希望得到的資源未被在服務(wù)器上發(fā)現(xiàn)。
          405
          Method Not Allowed
          請(qǐng)求行中指定的請(qǐng)求方法不能被用于請(qǐng)求相應(yīng)的資源。該響應(yīng)必須返回一個(gè)Allow 頭信息用以表示出當(dāng)前資源能夠接受的請(qǐng)求方法的列表。鑒于 PUT,DELETE 方法會(huì)對(duì)服務(wù)器上的資源進(jìn)行寫(xiě)操作,因而絕大部分的網(wǎng)頁(yè)服務(wù)器都不支持或者在默認(rèn)配置下不允許上述請(qǐng)求方法,對(duì)于此類(lèi)請(qǐng)求均會(huì)返回405錯(cuò)誤。
          406
          Not Acceptable
          請(qǐng)求的資源的內(nèi)容特性無(wú)法滿(mǎn)足請(qǐng)求頭中的條件,因而無(wú)法生成響應(yīng)實(shí)體。
          409
          Conflict
          由于和被請(qǐng)求的資源的當(dāng)前狀態(tài)之間存在沖突,請(qǐng)求無(wú)法完成。
          429
          Too Many Requests
          資源配額不足或達(dá)到速率限制。
          499
          Client Closed Request
          請(qǐng)求被客戶(hù)端取消。
          500
          Internal Server Error
          服務(wù)器內(nèi)部錯(cuò)誤
          501
          Not Implemented
          服務(wù)器不支持當(dāng)前請(qǐng)求所需要的某個(gè)功能。當(dāng)服務(wù)器無(wú)法識(shí)別請(qǐng)求的方法,并且無(wú)法支持其對(duì)任何資源的請(qǐng)求。
          502
          Bad Gateway
          作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),從上游服務(wù)器接收到無(wú)效的響應(yīng)。
          503
          Service Unavailable
          由于臨時(shí)的服務(wù)器維護(hù)或者過(guò)載,服務(wù)器當(dāng)前無(wú)法處理請(qǐng)求。這個(gè)狀況是臨時(shí)的,并且將在一段時(shí)間以后恢復(fù)。
          504
          Gateway Timeout
          作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),未能及時(shí)從上游服務(wù)器(URI標(biāo)識(shí)出的服務(wù)器,例如HTTP、FTP、LDAP)或者輔助服務(wù)器(例如DNS)收到響應(yīng)。
          505
          HTTP Version Not Supported
          服務(wù)器不支持,或者拒絕支持在請(qǐng)求中使用的 HTTP 版本。

          上面這些狀態(tài)碼覆蓋了 API 設(shè)計(jì)中大部分的情況,如果對(duì)某個(gè)狀態(tài)碼不清楚或者希望查看更完整的列表,可以參考 HTTP Status Code[6] 、維基百科-狀態(tài)碼[7]或者 RFC7231 Response Status Codes[8] 的內(nèi)容。

          七、錯(cuò)誤處理(Error Handling)

          如果出錯(cuò),應(yīng)該在 response body 中通過(guò) message 給出明確的錯(cuò)誤信息(一般來(lái)說(shuō),返回的信息中將 message 作為鍵名,出錯(cuò)詳情作為鍵值即可)。比如客戶(hù)端發(fā)送的請(qǐng)求有錯(cuò)誤,一般會(huì)返回 4XX Bad Request 結(jié)果。這個(gè)結(jié)果很模糊,給出錯(cuò)誤 message 的話(huà),能更好地讓客戶(hù)端知道具體哪里有問(wèn)題,進(jìn)行快速修改。

          {
           "message":"錯(cuò)誤詳情"
          }

          錯(cuò)誤詳情應(yīng)該可以幫助用戶(hù)輕松快捷地理解和解決API 錯(cuò)誤。通常,在編寫(xiě)錯(cuò)誤詳情時(shí)請(qǐng)考慮以下準(zhǔn)則:

          • 不要假設(shè)用戶(hù)是您 API 的專(zhuān)家用戶(hù)。用戶(hù)可能是客戶(hù)端開(kāi)發(fā)人員、操作人員、IT 人員或應(yīng)用的最終用戶(hù)。
          • 不要假設(shè)用戶(hù)了解有關(guān)服務(wù)實(shí)現(xiàn)的任何信息,或者熟悉錯(cuò)誤的上下文(例如日志分析)。
          • 如果可能,應(yīng)構(gòu)建錯(cuò)誤詳情,以便技術(shù)用戶(hù)(但不一定是 API 開(kāi)發(fā)人員)可以響應(yīng)錯(cuò)誤并改正。
          • 確保錯(cuò)誤詳情內(nèi)容簡(jiǎn)潔。如果需要,請(qǐng)?zhí)峁┮粋€(gè)鏈接,便于有疑問(wèn)的讀者提問(wèn)、提供反饋或詳細(xì)了解錯(cuò)誤詳情中不方便說(shuō)明的信息。此外,可使用詳細(xì)信息字段來(lái)提供更多信息。

          八、命名規(guī)則

          為了能夠長(zhǎng)時(shí)間在眾多 API 中為開(kāi)發(fā)者提供一致的體驗(yàn),API 使用的所有名稱(chēng)都應(yīng)該具有以下特點(diǎn):

          • 簡(jiǎn)單
          • 直觀
          • 一致

          這包括接口、資源、集合、方法和消息的名稱(chēng)。

          由于很多開(kāi)發(fā)者不是以英語(yǔ)為母語(yǔ),所以這些命名慣例的目標(biāo)之一是確保大多數(shù)開(kāi)發(fā)者可以輕松理解 API。對(duì)于方法和資源,我們鼓勵(lì)使用簡(jiǎn)單、直觀和少量的詞匯來(lái)命名。

          • API 名稱(chēng) 應(yīng)該 使用正確的美式英語(yǔ)。例如,使用美式英語(yǔ)的 license、color,而非英式英語(yǔ)的 licence、colour。
          • 為了簡(jiǎn)化命名, 可以 使用已被廣泛接受的簡(jiǎn)寫(xiě)形式或縮寫(xiě)。例如,API 優(yōu)于 Application Programming Interface。
          • 盡量使用直觀、熟悉的術(shù)語(yǔ)。例如,如果描述移除(和銷(xiāo)毀)一個(gè)資源,則刪除優(yōu)于擦除。
          • 使用相同的名稱(chēng)或術(shù)語(yǔ)命名同樣的概念,包括跨 API 共享的概念。
          • 避免名稱(chēng)過(guò)載。使用不同的名稱(chēng)命名不同的概念。
          • 避免在 API 的上下文以及更大的 API 生態(tài)系統(tǒng)中使用含糊不清且過(guò)于籠統(tǒng)的名稱(chēng)。這些名稱(chēng)可能導(dǎo)致對(duì) API 概念的誤解。相反,應(yīng)選擇能準(zhǔn)確描述 API 概念的名稱(chēng)。這對(duì)定義一階 API 元素(例如資源)的名稱(chēng)尤其重要。沒(méi)有要避免使用的名稱(chēng)的明確列表,因?yàn)槊總€(gè)名稱(chēng)都必須放在其他名稱(chēng)的上下文中進(jìn)行評(píng)估。實(shí)例、信息和服務(wù)是過(guò)去有問(wèn)題的名稱(chēng)的示例。所選擇的名稱(chēng)應(yīng)清楚地描述 API 概念(例如:什么的實(shí)例?),并將其與其他相關(guān)概念區(qū)分開(kāi)(例如:“alert”是指規(guī)則、信號(hào)還是通知?)。
          • 仔細(xì)考慮是否使用可能與常用編程語(yǔ)言中的關(guān)鍵字相沖突的名稱(chēng)。您可以使用這些名稱(chēng),但在 API 審核期間可能會(huì)觸發(fā)額外的審查。因此應(yīng)謹(jǐn)慎使用。

          九、認(rèn)證和授權(quán)(Authentication & Authorization)

          一般來(lái)說(shuō),讓任何人隨意訪(fǎng)問(wèn)公開(kāi)的 API 是不好的做法。驗(yàn)證和授權(quán)是兩件事情:

          • 驗(yàn)證(Authentication)是為了確定用戶(hù)是其申明的身份,比如提供賬戶(hù)的密碼。不然的話(huà),任何人偽造成其他身份(比如其他用戶(hù)或者管理員)是非常危險(xiǎn)的
          • 授權(quán)(Authorization)是為了保證用戶(hù)有對(duì)請(qǐng)求資源特定操作的權(quán)限。比如用戶(hù)的私人信息只能自己能訪(fǎng)問(wèn),其他人無(wú)法看到;有些特殊的操作只能管理員可以操作,其他用戶(hù)有只讀的權(quán)限等等

          如果沒(méi)有通過(guò)驗(yàn)證(提供的用戶(hù)名和密碼不匹配,token 不正確等),需要返回 401 Unauthorized[9]狀態(tài)碼,并在 body 中說(shuō)明具體的錯(cuò)誤信息;而沒(méi)有被授權(quán)訪(fǎng)問(wèn)的資源操作,需要返回 403 Forbidden[10] 狀態(tài)碼,還有詳細(xì)的錯(cuò)誤信息。

          NOTES: 借鑒于 Github,它對(duì)某些用戶(hù)未被授權(quán)訪(fǎng)問(wèn)的資源操作返回 404 Not Found[11],目的是為了防止私有資源的泄露(比如黑客可以自動(dòng)化試探用戶(hù)的私有資源,返回 403 的話(huà),就等于告訴黑客用戶(hù)有這些私有的資源)。

          十、限流(RateLimit)

          如果對(duì)訪(fǎng)問(wèn)的次數(shù)不加控制,很可能會(huì)造成 API 被濫用,甚至被 DDOS 攻擊[12]。根據(jù)使用者不同的身份對(duì)其進(jìn)行限流,可以防止這些情況,減少服務(wù)器的壓力。

          對(duì)用戶(hù)的請(qǐng)求限流之后,要有方法告訴用戶(hù)它的請(qǐng)求使用情況,本文檔推薦使用的三個(gè)相關(guān)的頭部:

          • X-RateLimit-Limit: 用戶(hù)每個(gè)小時(shí)允許發(fā)送請(qǐng)求的最大值
          • X-RateLimit-Remaining:當(dāng)前時(shí)間窗口剩下的可用請(qǐng)求數(shù)目
          • X-RateLimit-Rest: 時(shí)間窗口重置的時(shí)候,到這個(gè)時(shí)間點(diǎn)可用的請(qǐng)求數(shù)量就會(huì)變成 X-RateLimit-Limit 的值

          舉例:

          X-Ratelimit-Limit: 18000
          X-Ratelimit-Remaining: 17995
          X-Ratelimit-Reset: 1590570990

          如果允許沒(méi)有登錄的用戶(hù)使用 API(可以讓用戶(hù)試用),可以把 X-RateLimit-Limit 的值設(shè)置得很小,比如 60。沒(méi)有登錄的用戶(hù)是按照請(qǐng)求的 IP 來(lái)確定的,而登錄的用戶(hù)按照認(rèn)證后的信息來(lái)確定身份。

          對(duì)于超過(guò)流量的請(qǐng)求,可以返回 429 Too many requests[13] 狀態(tài)碼,并附帶錯(cuò)誤信息。

          十一、編寫(xiě)優(yōu)秀的文檔

          API 最終是給人使用的,不管是公司內(nèi)部,還是公開(kāi)的 API 都是一樣。即使我們遵循了上面提到的所有規(guī)范,設(shè)計(jì)的 API 非常優(yōu)雅,用戶(hù)還是不知道怎么使用我們的 API。最后一步,但非常重要的一步是:為你的 API 編寫(xiě)優(yōu)秀的文檔。

          對(duì)每個(gè)請(qǐng)求以及返回的參數(shù)給出說(shuō)明,最好給出一個(gè)詳細(xì)而完整地示例,提醒用戶(hù)需要注意的地方……反正目標(biāo)就是用戶(hù)可以根據(jù)你的文檔就能直接使用 API,而不是要發(fā)郵件給你,或者跑到你的座位上問(wèn)你一堆問(wèn)題。

          參考資料

          [1]

          OpenAPI Specfication: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md

          [2]

          Google API Design Guide: https://cloud.google.com/apis/design

          [3]

          阿里云: https://bytedance.feishu.cn/docs/doccnrP6Ud3YTavonOlxds9lzad#I1tZbK

          [4]

          Github API Design: https://developer.github.com/v3/#current-version

          [5]

          Versioning REST Services: https://www.informit.com/articles/article.aspx?p=1566460

          [6]

          HTTP Status Code: https://httpstatuses.com/

          [7]

          維基百科-狀態(tài)碼: https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81

          [8]

          RFC7231 Response Status Codes: https://tools.ietf.org/html/rfc7231#section-6

          [9]

          401 Unauthorized: https://httpstatuses.com/401

          [10]

          403 Forbidden: https://httpstatuses.com/403

          [11]

          404 Not Found: https://httpstatuses.com/404

          [12]

          DDOS 攻擊: https://en.wikipedia.org/wiki/Denial-of-service_attack

          [13]

          429 Too many requests: https://httpstatuses.com/429


          往期推薦

          如何從 100 億 URL 中找出相同的 URL?

          CEO不當(dāng)了,CTO也不做了!我要回去寫(xiě)代碼,這才是我所熱愛(ài)的!

          用谷歌搜索技術(shù)問(wèn)題一定比用百度好?也未必...

          好多大咖曾看他的書(shū)學(xué)習(xí)Java,如今這個(gè)男人的新作來(lái)了!

          Lombok!代碼簡(jiǎn)潔神器還是代碼“亞健康”元兇?



          喜歡本文歡迎轉(zhuǎn)發(fā),關(guān)注我訂閱更多精彩

          關(guān)注我回復(fù)「加群」,加入Spring技術(shù)交流群

          瀏覽 33
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  渣女AV在线 | 国产黄色免费视频 | 北条麻妃99精品青青久久 | 操骚逼黄色网址 | 黄色毛片一级 |