日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

API 本身的含義指應(yīng)用程序接口,包括所依賴的庫(kù)、平臺(tái)、操作系統(tǒng)提供的能力都可以叫做 API。我們?cè)谟懻撐⒎?wù)場(chǎng)景下的 API 設(shè)計(jì)都是指 WEB API,一般的實(shí)現(xiàn)有 RESTful、RPC等。API 代表了一個(gè)微服務(wù)實(shí)例對(duì)外提供的能力,因此 API 的傳輸格式(XML、JSON)對(duì)我們?cè)谠O(shè)計(jì) API 時(shí)的影響并不大。

API設(shè)計(jì)的幾條原則

 

API 設(shè)計(jì)是微服務(wù)設(shè)計(jì)中非常重要的環(huán)節(jié),代表服務(wù)之間交互的方式,會(huì)影響服務(wù)之間的集成。 通常來(lái)說(shuō),一個(gè)好的 API 設(shè)計(jì)需要滿足兩個(gè)主要的目的:

  • 平臺(tái)獨(dú)立性。 任何客戶端都能消費(fèi) API,而不需要關(guān)注系統(tǒng)內(nèi)部實(shí)現(xiàn)。API 應(yīng)該使用標(biāo)準(zhǔn)的協(xié)議和消息格式對(duì)外部提供服務(wù)。傳輸協(xié)議和傳輸格式不應(yīng)該侵入到業(yè)務(wù)邏輯中,也就是系統(tǒng)應(yīng)該具備隨時(shí)支持不同傳輸協(xié)議和消息格式的能力。
  • 系統(tǒng)可靠性。 在 API 已經(jīng)被發(fā)布和非 API 版本改變的情況下,API 應(yīng)該對(duì)契約負(fù)責(zé),不應(yīng)該導(dǎo)致數(shù)據(jù)格式發(fā)生破壞性的修改。在 API 需要重大更新時(shí),使用版本升級(jí)的方式修改,并對(duì)舊版本預(yù)留下線時(shí)間窗口。

實(shí)踐中發(fā)現(xiàn),API 設(shè)計(jì)是一件很難的事情,同時(shí)也很難衡量設(shè)計(jì)是否優(yōu)秀。根據(jù)系統(tǒng)設(shè)計(jì)和消費(fèi)者的角度,給出了一些簡(jiǎn)單的設(shè)計(jì)原則。

使用成熟度合適的 RESTful API

RESTful 風(fēng)格的 API 具有一些天然的優(yōu)勢(shì),例如通過(guò) HTTP 協(xié)議降低了客戶端的耦合,具有極好的開(kāi)放性。因此越來(lái)越多的開(kāi)發(fā)者使用 RESTful 這種風(fēng)格設(shè)計(jì) API,但是 RESTful 只能算是一個(gè)設(shè)計(jì)思想或理念,不是一個(gè) API 規(guī)范,沒(méi)有一些具體的約束條件。

因此在設(shè)計(jì) RESTful 風(fēng)格的 API 時(shí)候,需要參考 RESTful 成熟度模型。

API設(shè)計(jì)的幾條原則

RESTful 成熟度模型。

根據(jù)自己的應(yīng)用場(chǎng)景選擇對(duì)應(yīng)的成熟度模型,一般來(lái)說(shuō)系統(tǒng)成熟度模型在 Level 2左右。

避免簡(jiǎn)單封裝

API應(yīng)該服務(wù)業(yè)務(wù)能力的封裝,避免簡(jiǎn)單封裝讓API徹底變成了數(shù)據(jù)庫(kù)操作接口。例如標(biāo)記訂單狀態(tài)為已支付,應(yīng)該提供形如POST /orders/1/pay這樣的API。而非PATCH /orders/1,然后通過(guò)具體的字段更新訂單。

因?yàn)橛唵沃Ц妒怯芯唧w的業(yè)務(wù)邏輯,可能涉及到大量復(fù)雜的操作,使用簡(jiǎn)單的更新操作將業(yè)務(wù)邏輯泄漏到系統(tǒng)之外。同時(shí)系統(tǒng)外也需要知道訂單狀態(tài) 這個(gè)內(nèi)部使用的字段。

更重要的是,破壞了業(yè)務(wù)邏輯的封裝,同時(shí)也會(huì)影響其他非功能需求。例如,權(quán)限控制、日志記錄、通知等。

關(guān)注點(diǎn)分離

好的接口應(yīng)該做到不多東西,不少東西。 怎么理解呢?在用戶修改密碼和修改個(gè)人資料的場(chǎng)景中,這兩個(gè)操作看起來(lái)很類似,然后設(shè)計(jì)API的時(shí)候使用了一個(gè)通用的/users/1/udpateURI。

然后定義了一個(gè)對(duì)象,這個(gè)對(duì)象可能直接使用了User這個(gè)類:

{
  "username": "用戶名",
  "password": "密碼"
}

這個(gè)對(duì)象在修改用戶名的時(shí)候, password是不必要的,但是在修改密碼的操作中,一個(gè)password字段卻不夠用了,可能還需要

confirmPassword。

于是這個(gè)接口變成:

{
  "username": "用戶名",
  "password":"密碼",
  "confirmPassword":"重復(fù)密碼"
}

這種類的復(fù)用會(huì)給后續(xù)維護(hù)的開(kāi)發(fā)者帶來(lái)困惑,同時(shí)對(duì)消費(fèi)者也非常不友好。合理的設(shè)計(jì)應(yīng)該是兩個(gè)分離的 API:

// POST /users/{userId}/password

{
  "password":"密碼",
  "confirmPassword":"重復(fù)密碼"
}
// PATCH /users/{userId}

{
  "username":"用戶名",
  "xxxx":"其他可更新的字段"
}

對(duì)應(yīng)的實(shí)現(xiàn),在 JAVA 中需要定義兩個(gè) DTO,分別處理不同的接口。這也體現(xiàn)了面向?qū)ο笏枷胫械年P(guān)注點(diǎn)分離。

完全窮盡,彼此獨(dú)立

API 之間盡量遵守完全窮盡,彼此獨(dú)立 (MECE) 原則,不應(yīng)該提供相互疊加的 API。例如訂單和訂單項(xiàng)這兩個(gè)資源,如果提供了形如 PUT /orders/1/order-items/1 這樣的接口去修改訂單項(xiàng),接口 PUT /orders/1 就不應(yīng)該具備處理某一個(gè) order-item 的能力。

這樣的好處是不會(huì)存在重復(fù)的 API,造成維護(hù)和理解上的復(fù)雜性。如何做到完全窮盡和彼此獨(dú)立呢?

簡(jiǎn)單的方法是使用一個(gè)表格設(shè)計(jì) API,標(biāo)出每個(gè) URI 具備的能力。

API設(shè)計(jì)的幾條原則

API設(shè)計(jì)表格

資源 URL 設(shè)計(jì)來(lái)源于 DDD 領(lǐng)域建模就非常簡(jiǎn)單了,聚合根作為根 URL,實(shí)體作為二級(jí) URI 設(shè)計(jì)。聚合根之間應(yīng)該徹底沒(méi)有任何聯(lián)系,實(shí)體和聚合根之間的責(zé)任應(yīng)該明確。

產(chǎn)生這類問(wèn)題的根源還是缺乏合理的抽象。如果存在 API 中可以通過(guò)用戶組操作用戶,通過(guò)用戶的 URI 操作用戶屬于的用戶組,這其中的問(wèn)題是缺少了成員這一概念。用戶組下面的本質(zhì)上并不是用戶,而是用戶和用戶組的關(guān)系,即成員。

版本化

一個(gè)對(duì)外開(kāi)放的服務(wù),極大的概率會(huì)發(fā)生變化。業(yè)務(wù)變化可能修改 API 參數(shù)或響應(yīng)數(shù)據(jù)結(jié)構(gòu),以及資源之間的關(guān)系。一般來(lái)說(shuō),字段的增加不會(huì)影響舊的客戶端運(yùn)行。但是當(dāng)存在一些破壞性修改時(shí),就需要使用新的版本將數(shù)據(jù)導(dǎo)向到新的資源地址。

版本信息的傳輸,可以通過(guò)下面幾種方式

  • URI 前綴
  • Header
  • Query

比較推薦的做法是使用 URI 前綴,例如/v1/users/表達(dá)獲取 v1 版本下的用戶列表。

常見(jiàn)的反模式是通過(guò)增加 URI 后綴來(lái)實(shí)現(xiàn)的,例如/users/1/updateV2。這樣做的缺陷是版本信息侵入到業(yè)務(wù)邏輯中,對(duì)路由的統(tǒng)一管理帶來(lái)不便。

使用 Header 和 Query 發(fā)送版本信息則較為相似,不同之處在于,使用 URI 前綴在 MVC 框架中實(shí)現(xiàn)相對(duì)簡(jiǎn)單,只需要定義好路由即可。使用 Header 和 Query 還需要編寫額外的攔截器。

合理命名

設(shè)計(jì) API 時(shí)候的命名涉及多個(gè)地方:URI、請(qǐng)求參數(shù)、響應(yīng)數(shù)據(jù)等。通常來(lái)說(shuō)最主要,也是最難的一個(gè)是全局命名統(tǒng)一。

其次,命名需要注意這些:

  • 盡可能和領(lǐng)域名詞保持一致,例如聚合根、實(shí)體、事件等
  • RESTful 設(shè)計(jì)的 URI 中使用名詞復(fù)數(shù)
  • 盡可能不要過(guò)度簡(jiǎn)寫,例如將 user 簡(jiǎn)寫成usr
  • 盡可能使用不需要編碼的字符

用領(lǐng)域名詞來(lái)對(duì) API 設(shè)計(jì)命名不是一件特別難的事情。識(shí)別出的領(lǐng)域名詞可以直接作為 URI 來(lái)使用。如果存在多個(gè)單詞的連接可以使用中橫線,例如/orders/1/order-items

安全

安全是任何一項(xiàng)軟件設(shè)計(jì)都必須要考慮的事情,對(duì)于 API 設(shè)計(jì)來(lái)說(shuō),暴露給內(nèi)部系統(tǒng)的 API 和開(kāi)放給外部系統(tǒng)的 API 略有不同。

API設(shè)計(jì)的幾條原則

 

內(nèi)部系統(tǒng),更多的是考慮是否足夠健壯。對(duì)接收的數(shù)據(jù)有足夠的驗(yàn)證,并給出錯(cuò)誤信息,而不是什么信息都接收,然后內(nèi)部業(yè)務(wù)邏輯應(yīng)該邊界值的影響變得莫名其妙。

而對(duì)于外部系統(tǒng)的 API 則有更多的挑戰(zhàn)。

  • 錯(cuò)誤的調(diào)用方式
  • 接口濫用
  • 瀏覽器消費(fèi) API 時(shí)因安全漏洞導(dǎo)致的非法訪問(wèn)

所以設(shè)計(jì) API 時(shí)應(yīng)該考慮響應(yīng)的應(yīng)對(duì)措施。針對(duì)錯(cuò)誤的調(diào)用方式,API 不應(yīng)該進(jìn)入業(yè)務(wù)處理流程,及時(shí)給出錯(cuò)誤信息;對(duì)于接口濫用的情況,需要做一些限速的方案;對(duì)于一些瀏覽器消費(fèi)者的問(wèn)題,可以在讓 API 返回一些安全增強(qiáng)頭部,例如:X-XSS-Protection、Content-Security-Policy 等。

API 設(shè)計(jì)評(píng)審清單

  • URI 命名是否通過(guò)聚合根和實(shí)體統(tǒng)一
  • URI 命名是否采用名詞復(fù)數(shù)和連接線
  • URI 命名是否都是單詞小寫
  • URI 是否暴露了不必要的信息,例如/cgi-bin
  • URI 規(guī)則是否統(tǒng)一
  • 資源提供的能力是否彼此獨(dú)立
  • URI 是否存在需要編碼的字符
  • 請(qǐng)求和返回的參數(shù)是否不多不少
  • 資源的 ID 參數(shù)是否通過(guò) PATH 參數(shù)傳遞
  • 認(rèn)證和授權(quán)信息是否暴露到 query 參數(shù)中
  • 參數(shù)是否使用奇怪的縮寫
  • 參數(shù)和響應(yīng)數(shù)據(jù)中的字段命名統(tǒng)一
  • 是否存在無(wú)意義的對(duì)象包裝 例如{"data":{}'}
  • 出錯(cuò)時(shí)是否破壞約定的數(shù)據(jù)結(jié)構(gòu)
  • 是否使用合適的狀態(tài)碼
  • 是否使用合適的媒體類型
  • 響應(yīng)數(shù)據(jù)的單復(fù)是否和數(shù)據(jù)內(nèi)容一致
  • 響應(yīng)頭中是否有緩存信息
  • 是否進(jìn)行了版本管理
  • 版本信息是否作為 URI 的前綴存在
  • 是否提供 API 服務(wù)期限
  • 是否提供了 API 返回所有 API 的索引
  • 是否進(jìn)行了認(rèn)證和授權(quán)
  • 是否采用 HTTPS
  • 是否檢查了非法參數(shù)
  • 是否增加安全性的頭部
  • 是否有限流策略
  • 是否支持 CORS
  • 響應(yīng)中的時(shí)間格式是否采用ISO 8601標(biāo)準(zhǔn)
  • 是否存在越權(quán)訪問(wèn)

更多精彩洞見(jiàn),請(qǐng)關(guān)注微信公眾號(hào):ThoughtWorks洞見(jiàn)

文/ThoughtWorks少個(gè)分號(hào)

分享到:
標(biāo)簽:設(shè)計(jì) API
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定