真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何保障API設(shè)計(jì)的穩(wěn)定性

如何保障API設(shè)計(jì)的穩(wěn)定性,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的吳橋網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

計(jì)算機(jī)行業(yè)有句名言 —— 計(jì)算機(jī)科學(xué)領(lǐng)域的任何問(wèn)題,都可以通過(guò)增加一個(gè)間接的中間層來(lái)解決。

當(dāng)前的計(jì)算機(jī)領(lǐng)域,無(wú)論廣度還是深度,已經(jīng)沒(méi)有一個(gè)人能完全掌握了。但是,通過(guò)各種中間層的組合使用,我們不需要了解其內(nèi)部細(xì)節(jié),也可以像搭積木一樣,開發(fā)出各種有趣的服務(wù)和應(yīng)用。
而各個(gè)中間層之所以能組合工作,正是因?yàn)榇蠹叶纪ㄟ^(guò)定義好的 API 交互和通信。每個(gè)模塊在對(duì)外提供經(jīng)過(guò)抽象 API 的同時(shí),也需要使用其他模塊的 API 作為自身運(yùn)行的基礎(chǔ)。

今天我們來(lái)聊聊在設(shè)計(jì) API 過(guò)程保障穩(wěn)定性的一些實(shí)踐。

無(wú)處不在的 API

API(Application Programming Interface) 又稱為應(yīng)用編程接口。

而接口,本質(zhì)可以理解為契約,一種約定。
計(jì)算機(jī)接口的概念起源于硬件。早期各家研發(fā)的各種元器件都不通用也沒(méi)有標(biāo)準(zhǔn),相互使用非常困難,于是大家約定了功能和規(guī)格,就產(chǎn)生了接口,后來(lái)蔓延到軟件中。

接口蔓延到軟件之后,又分為 ABI(Application Binary Interface) 和 API(Application Programming Interface) 。
前者主要約定了二進(jìn)制的運(yùn)行和訪問(wèn)的規(guī)則,后者則 專注于邏輯模塊的交互。本文以下內(nèi)容僅討論開發(fā)者經(jīng)常接觸的 API。

很多人對(duì) API 的印象只是包含一些函數(shù)的 Class 或 頭文件。但 API 在我們生活中無(wú)處不在,只是我們有時(shí)并沒(méi)有注意到。

比如,當(dāng)我們?cè)趽艽螂娫挄r(shí),手機(jī)和基站通信的整個(gè)系統(tǒng)是非常復(fù)雜的。

 如何保障API設(shè)計(jì)的穩(wěn)定性

好在我們不需要了解內(nèi)部的細(xì)節(jié),僅需要把 11 位的電話號(hào)碼傳給“電話系統(tǒng)”的接口就可以,而隱藏的國(guó)家區(qū)號(hào)(如+86)可以理解為接口的默認(rèn)參數(shù)。
這個(gè)高度抽象的 API 背后,隱藏了非常多的細(xì)節(jié)。借助上面的中間層理論,我們可以系統(tǒng)性地討論設(shè)計(jì)一個(gè) API 所需要考慮哪些內(nèi)容。

 如何保障API設(shè)計(jì)的穩(wěn)定性

模塊對(duì)上層暴露的 API 如何被使用?

API 從使用的耦合方式上,可以分為兩類:一種是通過(guò)協(xié)議調(diào)用,如調(diào)用 HTTP 接口;另一種是語(yǔ)言直接通過(guò)聲明調(diào)用。
如設(shè)計(jì) HTTP Restful API 時(shí),并不需要關(guān)心使用者的操作系統(tǒng)、使用的編程語(yǔ)言、內(nèi)存線程管理等,因此會(huì)比后者簡(jiǎn)單一些。

API 從使用者的規(guī)模和可控范圍上,可以分為 LSUD(Larget Set of Unkown Developers) 和 SSKD(Small Set of Kown Developers) 兩種。
前者一般都是公網(wǎng)開放的云服務(wù),任何開發(fā)者都可以使用,無(wú)法提前預(yù)知以何種姿勢(shì)被使用,版本也不可控制。融云提供的通信云就是這種 API。
后者用戶群有限,一般都在同一家公司或團(tuán)隊(duì)內(nèi)。比如前段時(shí)間比較火的組件化,即對(duì)內(nèi)提供的模塊化 API,使用范圍和方式均可控,在更新時(shí)一般不用太糾結(jié)向后兼容。

API 的第一受眾是人,然后才是機(jī)器,所以“可理解性”在設(shè)計(jì)時(shí)需要優(yōu)先考慮。
而良好的 API 文檔、簡(jiǎn)單扼要的 Demo、關(guān)鍵的 log,可以提升 API 使用者的體驗(yàn)。

API 所屬模塊對(duì)下層有什么依賴?

API 所屬模塊都運(yùn)行在一定的地址空間中。而其中的環(huán)境變量、加載庫(kù)、內(nèi)存和線程模型、系統(tǒng)和語(yǔ)言特性都需要考慮。

API 所屬模塊的內(nèi)部實(shí)現(xiàn)對(duì)其他層有什么影響?

一般而言,設(shè)計(jì)良好的 API 在使用時(shí),并不需要理解其內(nèi)部實(shí)現(xiàn)。但如果能了解其內(nèi)部架構(gòu)并輔助關(guān)鍵 log,有助于提升使用 API 的效率。
并且模塊的內(nèi)部實(shí)現(xiàn),有時(shí)也會(huì)影響到 API 設(shè)計(jì)的風(fēng)格。
如一個(gè)強(qiáng)依賴 IO 的接口,可能需要使用異步的方式。大量異步的方式,就衍生出了 RxJava 等框架。

向后兼容

因?yàn)?API 如此重要,涉及的范圍又如此廣泛,廣大開發(fā)者對(duì) API 的向后兼容可以說(shuō)要求非常高。
畢竟誰(shuí)也不想在開發(fā)過(guò)程中,頻繁的更新接口和代碼,想想《 swift 從入門到精通到再次入門到再再次入門》的慘案就心有余悸。

我們不僅問(wèn),為什么很多公司或者項(xiàng)目都無(wú)法向后兼容,僅僅是投入不夠或不夠重視,還是說(shuō) 100% 的向后兼容實(shí)際就是不可能的?

假設(shè)設(shè)計(jì)是理想和經(jīng)過(guò)論證的,正如一個(gè)完美的圓圈。
設(shè)計(jì)是要落實(shí)到編碼中的,而編碼的過(guò)程中總是不可避免的引入一些 bug,而帶著 bug 的某個(gè)版本實(shí)現(xiàn),其實(shí)正如一個(gè) Amoeba 變形蟲,形態(tài)是不固定的。而隨著版本不斷演進(jìn),不可避免會(huì)產(chǎn)生一定的差異。

第一個(gè)版本實(shí)現(xiàn):

如何保障API設(shè)計(jì)的穩(wěn)定性

第二個(gè)版本實(shí)現(xiàn):

 如何保障API設(shè)計(jì)的穩(wěn)定性

所以說(shuō) 100% 向后兼容本身就是不可能的。

因此,大家平時(shí)在談?wù)?API 穩(wěn)定性時(shí),其實(shí)默認(rèn)是可以包含一定程度變更的。

但由于 API 涉及的范圍太廣泛,保障向后兼容都需要極大代價(jià)。
比如 Linux 就希望快速迭代,完全不保證 API 的穩(wěn)定性。針對(duì)這個(gè)問(wèn)題,Linux 還特意寫了 stable-api-nonsense 文檔。
有興趣的可以點(diǎn)擊閱讀:stable-api-nonsense.rst

漸進(jìn)式改進(jìn)

所以說(shuō),保障 API 的穩(wěn)定性會(huì)面臨很多挑戰(zhàn),比如:
* 業(yè)務(wù)形態(tài)還不穩(wěn)定,還在高速發(fā)展
* 業(yè)務(wù)和 API 歷史包袱較重
* 多個(gè)平臺(tái)和語(yǔ)言的特性不一致
* 用戶群和使用方式不明確

我們回顧一下正常的開發(fā)流程,看看是否能通過(guò)一些指標(biāo)和工具,改善 API 的穩(wěn)定性,主要涉及:需求、設(shè)計(jì)、編碼、Review、測(cè)試、發(fā)布、反饋等步驟。

※需求

普通的產(chǎn)品開發(fā),在啟動(dòng)的時(shí)候,用戶需求都比較明確,但對(duì)于 LSUD 的云服務(wù)而言,無(wú)法提前預(yù)知用戶群都有哪些,以及用戶在他的產(chǎn)品中如何使用 API。
這容易造成,沒(méi)有明確的用戶需求,API 就不好進(jìn)行設(shè)計(jì)和迭代,沒(méi)有設(shè)計(jì)就沒(méi)有用戶,需求更無(wú)從談起。這是一個(gè)雞生蛋、蛋生雞的問(wèn)題。

建議可以在 API 發(fā)布之前,內(nèi)部先針對(duì)典型的使用場(chǎng)景,設(shè)計(jì)幾個(gè)完整的 Demo,驗(yàn)證 API 的設(shè)計(jì)和使用是否合理。
需要注意的是,Demo 需要有完整應(yīng)用場(chǎng)景,達(dá)到上架地步,如果能內(nèi)部使用, Eating your own dog food 最好,過(guò)于簡(jiǎn)單的 Demo 無(wú)法提前暴露 API 的使用問(wèn)題。

Demo 的開發(fā)人員最好與 API 的設(shè)計(jì)者有所區(qū)分,避免思維固化,更多內(nèi)容大家可以參照 Rust 語(yǔ)言開發(fā)在自舉過(guò)程中的一些實(shí)踐。

※設(shè)計(jì)

在設(shè)計(jì) API 的時(shí)候,有很多需要注意的點(diǎn)和普通開發(fā)不太一樣。

普通開發(fā),快速實(shí)現(xiàn)功能始終被放在第一位。比如大家會(huì)用一些敏捷開發(fā)的方式,優(yōu)先實(shí)現(xiàn)功能再快速迭代等。
但 API 設(shè)計(jì)時(shí),接口無(wú)法頻繁變更,所以首先需要考慮的是“少”,少即是多。

l 每個(gè) API 做的事情要少

一個(gè)接口只做一件事,把這個(gè)事情做好就足夠了。
需要避免為了討好某個(gè)場(chǎng)景,在一個(gè) API 上進(jìn)行復(fù)雜的組合邏輯,提供一個(gè)類似語(yǔ)法糖的接口。否則,場(chǎng)景的業(yè)務(wù)自身在演進(jìn)時(shí),很難保證 API 的行為不變。
如果需要支持多種業(yè)務(wù),可以考慮將 API 分層,比如融云客戶端的 API 會(huì)分為下面幾層。

 如何保障API設(shè)計(jì)的穩(wěn)定性

舉個(gè)例子,融云考慮通用性,基于訂閱分發(fā)的模型,抽象了 RTCLib,客戶端能處理媒體的任意流,非常的靈活,但是對(duì)于用戶而言開發(fā)代價(jià)可能高些,要思考和做的工作比較多。
考慮到大量的用戶,其實(shí)需要的是音視頻通話的業(yè)務(wù),基于 RTCLib,融云分裝了不帶 UI 的 CallLib 以及集成了 UI 的 CallKit。
如果一個(gè)用戶,需求和微信的音視頻通話類似,可以集成帶 UI 界面的 CallKit,開發(fā)效率會(huì)非常高;
如果用戶對(duì)通話音視頻通話 UI 的交互有大量需求,可以基于 CallLib 進(jìn)行開發(fā),對(duì) UI 可以進(jìn)行各種定制。

l 暴露的信息要少

成熟的 API 設(shè)計(jì)者都會(huì)盡可能的隱藏內(nèi)部實(shí)現(xiàn)細(xì)節(jié)。
比如字段不應(yīng)該直接暴露而是通過(guò) Getter/Setter 提供,不需要的類、方法、字段都應(yīng)該隱藏,都已經(jīng)成為各個(gè)語(yǔ)言的基礎(chǔ)要求,在此就不細(xì)述了。
但容易被忽略的一點(diǎn)需要提醒大家,應(yīng)盡量隱藏技術(shù)棧的信息。
比如:API http://api.example.com/cgi-bin/get_user.php?user=100,就明顯混入了很多無(wú)用的信息,并且以后技術(shù)切換升級(jí)想維持 API 穩(wěn)定非常麻煩。

l 行為擴(kuò)散要少

在語(yǔ)言直接調(diào)用的 API 中,需要避免基礎(chǔ)接口通過(guò)繼承導(dǎo)致行為擴(kuò)散。
在普通的編碼過(guò)程中,抽象類和繼承都是面向?qū)ο蟮膹?qiáng)大武器。但是對(duì)于 API,更建議通過(guò)組合使用。
比如一個(gè)管理生命周期的類,如果被繼承,子類有些行為就有可能被修改而導(dǎo)致出錯(cuò)。這時(shí)候建議使用 Interface + 工廠的方法提供實(shí)例。
由于 Java 8 之前 interface 沒(méi)有 default 實(shí)現(xiàn),為了避免增加功能需要頻繁修改接口,可以使用 final class。
Objetive-C 則可以使用 __attribute__((objc_subclassing_restricted)) 和 __attribute__((objc_requires_super) 控制子類繼承行為。

l 畫風(fēng)切換要少

API 命名要做到多個(gè)平臺(tái)的業(yè)務(wù)命名統(tǒng)一,與每個(gè)平臺(tái)的風(fēng)格統(tǒng)一。
這點(diǎn) HTTP 的接口要簡(jiǎn)單一些,只需要選定一種風(fēng)格即可,Restful 或者 GraphQL 或者自己定義。
語(yǔ)言調(diào)用的 API 命名,建議首先遵循平臺(tái)的風(fēng)格,然后再是參考語(yǔ)言標(biāo)準(zhǔn),最后才考慮團(tuán)隊(duì)的風(fēng)格。
比如:iOS 平臺(tái)的 API 開發(fā),需要首先參照 iOS 的命名風(fēng)格,did 和 will 之類的時(shí)態(tài)就非常有特色。
命名上細(xì)節(jié)較多,詞匯、時(shí)態(tài)、單復(fù)數(shù)、介詞、?小寫、同步異步風(fēng)格等都需要考量,需要長(zhǎng)時(shí)間的積累。

l 理解成本要少

一般 API 每個(gè)接口都會(huì)有相應(yīng)的注釋說(shuō)明,但是值得注意的是,大部分開發(fā)者并不看注釋。
大部分開發(fā)者對(duì)接口的了解,都僅源于 IDE 的補(bǔ)全和提醒。一個(gè)接口看著像就直接用,不行再換一個(gè)試試,這其實(shí)是一種經(jīng)驗(yàn)式編程的方式。
也就意味著接口命名需要提高可理解性。有一個(gè)辦法可以驗(yàn)證,將接口的所有注釋抹掉,使用者能否非常直接的看懂每個(gè)接口的含義。如果很困難,則需要改進(jìn)。

API 設(shè)計(jì)還有一處和普通開發(fā)不太一致。普通開發(fā)設(shè)計(jì)好架構(gòu)即可,每個(gè)模塊的開發(fā)可能是同一個(gè)人,接口并不需要在設(shè)計(jì)時(shí)確定下來(lái)。
但是 API 的設(shè)計(jì)階段,需要進(jìn)行 Review 并直接確定接口的設(shè)計(jì),以保證多端在開發(fā)時(shí)遵循完全一直的規(guī)則。

※編碼

在 API 的編碼過(guò)程中,有以下幾點(diǎn)需要注意。

在 API 中,預(yù)定義好版本號(hào)。
這個(gè)主要是針對(duì) HTTP API,如:http://api.example.com/v1/users/12345?fields=name,age。 如果目前僅有一個(gè)版本,也可以暫時(shí)不加,第二版時(shí)再區(qū)分。

注意 API 版本檢查。
當(dāng)分層提供多種 API 時(shí),每層 API 需要在啟動(dòng)時(shí),先校驗(yàn)一下版本號(hào),避免不匹配的情況。
比如在以下 Java 代碼中,大家可能覺(jué)得判斷版本號(hào)相等的代碼非常奇怪,應(yīng)該永遠(yuǎn)是 true 才對(duì)。

 如何保障API設(shè)計(jì)的穩(wěn)定性

但是抽象類和實(shí)現(xiàn)類出現(xiàn)在不同的分層模塊中,并且實(shí)現(xiàn)類先編譯,抽象類版本更新后再編譯,就會(huì)出現(xiàn)不一致的情況。有很多語(yǔ)言或平臺(tái)能提供類似的方式來(lái)確定版本。

提供規(guī)范性的 log 輸出。
普通開發(fā)的log,主要用于自己定位問(wèn)題。但是 API 在編碼時(shí),最好針對(duì)性的添加一些 log,有利于 API 的使用者理解并簡(jiǎn)單排查問(wèn)題。
但出于性能考慮,需要定義好 log 的級(jí)別并可以調(diào)整。

注意廢棄與遷移。
當(dāng)一個(gè)以前設(shè)計(jì)的 API 不再符合要求或者有重大問(wèn)題時(shí),我們可以對(duì)外標(biāo)記成已廢棄,并在注釋中建議使用者遷移到另一個(gè)接口。
如果是類似的被廢棄接口,內(nèi)部編碼時(shí)最好能使用新的接口來(lái)實(shí)現(xiàn),以降低向后兼容的維護(hù)成本。
HTTP 的 API,需要預(yù)定義好遷移的錯(cuò)誤碼,比如在 HTTP 規(guī)范中,可以使用 410 Gone 說(shuō)明已經(jīng)不再支持某個(gè)接口。

※Review

API 的 Review 基于普通開發(fā)的 Code Review。
如果基礎(chǔ)的 Code Review 都沒(méi)有做好,肯定無(wú)法保障 API 的質(zhì)量和穩(wěn)定性。

可以通過(guò)一些工具,為 API 的 Review 提供一些參考報(bào)告。
比如可以使用 SonarLint 分析代碼復(fù)雜度,如果接口層的代碼復(fù)雜度較高,會(huì)是一個(gè)危險(xiǎn)的信號(hào)。
還可以借助 Java 反射、Clang 語(yǔ)法分析,獲取當(dāng)前的 API 接口列表,生成接口變更報(bào)告,也有利于減少無(wú)用接口的暴露。
另外,自動(dòng)化工具生成的接口文檔也是 Review 重要的一環(huán)。

※測(cè)試

在測(cè)試環(huán)節(jié),我們可以通過(guò) unit test 來(lái)關(guān)注 API 的穩(wěn)定性。
與敏捷開發(fā)經(jīng)常修改 test case 不同,API 的 test case 基本代表了接口的穩(wěn)定性。所以在修改舊 case 時(shí)需要特別明確,是 case 自身的 bug 還是接口行為發(fā)生了變更。

※發(fā)布

我們可以通過(guò)區(qū)分 dev 和 stable 版本,為不同階段的開發(fā)者提供更好的體驗(yàn)。

dev 版本包含最新的功能,但是 API 接口有變更風(fēng)險(xiǎn)。stable 版本 API 穩(wěn)定,但功能不一定是最新的。
如果開發(fā)者還在開發(fā)過(guò)程中,可以選用最新的 dev 版本,基于最新 API 開發(fā)。
如果應(yīng)用已經(jīng)上線,可以選擇升級(jí)直接到最新的 stable 版本。

關(guān)于如何保障API設(shè)計(jì)的穩(wěn)定性問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。


新聞名稱:如何保障API設(shè)計(jì)的穩(wěn)定性
文章鏈接:http://weahome.cn/article/jhoidh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部