API的四種類型
API 同時也是一種中間件,為各種不同平臺提供數(shù)據(jù)共享。根據(jù)單個或分布式平臺上不同軟件應(yīng)用程序間的數(shù)據(jù)共享性能,可以將 API 分為四種類型:
遠(yuǎn)程過程調(diào)用(RPC):通過作用在共享數(shù)據(jù)緩存器上的過程(或任務(wù))實(shí)現(xiàn)程序間的通信。
標(biāo)準(zhǔn)查詢語言(SQL):是標(biāo)準(zhǔn)的訪問數(shù)據(jù)的查詢語言,通過通用數(shù)據(jù)庫實(shí)現(xiàn)應(yīng)用程序間的數(shù)據(jù)共享。
文件傳輸:文件傳輸通過發(fā)送格式化文件實(shí)現(xiàn)應(yīng)用程序間數(shù)據(jù)共享。
信息交付:指松耦合或緊耦合應(yīng)用程序間的小型格式化信息,通過程序間的直接通信實(shí)現(xiàn)數(shù)據(jù)共享。
當(dāng)前應(yīng)用于 API 的標(biāo)準(zhǔn)包括 ANSI 標(biāo)準(zhǔn) SQL API。另外還有一些應(yīng)用于其它類型的標(biāo)準(zhǔn)尚在制定之中。API 可以應(yīng)用于所有計(jì)算機(jī)平臺和操作系統(tǒng)。這些 API 以不同的格式連接數(shù)據(jù)(如共享數(shù)據(jù)緩存器、數(shù)據(jù)庫結(jié)構(gòu)、文件框架)。每種數(shù)據(jù)格式要求以不同的數(shù)據(jù)命令和參數(shù)實(shí)現(xiàn)正確的數(shù)據(jù)通信,但同時也會產(chǎn)生不同類型的錯誤。因此,除了具備執(zhí)行數(shù)據(jù)共享任務(wù)所需的知識以外,這些類型的 API 還必須解決很多網(wǎng)絡(luò)參數(shù)問題和可能的差錯條件,即每個應(yīng)用程序都必須清楚自身是否有強(qiáng)大的性能支持程序間通信。相反由于這種 API 只處理一種信息格式,所以該情形下的信息交付 API 只提供較小的命令、網(wǎng)絡(luò)參數(shù)以及差錯條件子集。正因?yàn)槿绱?,交?API 方式大大降低了系統(tǒng)復(fù)雜性,所以當(dāng)應(yīng)用程序需要通過多個平臺實(shí)現(xiàn)數(shù)據(jù)共享時,采用信息交付 API 類型是比較理想的選擇。
API 與圖形用戶接口(GUI)或命令接口有著鮮明的差別:API 接口屬于一種操作系統(tǒng)或程序接口,而后兩者都屬于直接用戶接口。
有時公司會將 API 作為其公共開放系統(tǒng)。也就是說,公司制定自己的系統(tǒng)接口標(biāo)準(zhǔn),當(dāng)需要執(zhí)行系統(tǒng)整合、自定義和程序應(yīng)用等操作時,公司所有成員都可以通過該接口標(biāo)準(zhǔn)調(diào)用源代碼,該接口標(biāo)準(zhǔn)被稱之為開放式 API。? ? ? ?
?API設(shè)計(jì)
背景
目前互聯(lián)網(wǎng)上充斥著大量的關(guān)于RESTful API(為方便,下文中“RESTful API ”簡寫為“API”)如何設(shè)計(jì)的文章,然而卻沒有一個”萬能“的設(shè)計(jì)標(biāo)準(zhǔn):如何鑒權(quán)?API 格式如何?你的API是否應(yīng)該加入版本信息?當(dāng)你開始寫一個app的時候,特別是后端模型部分已經(jīng)寫完的時候,你不得不殫精竭慮的設(shè)計(jì)和實(shí)現(xiàn)自己app的public API部分。因?yàn)橐坏┌l(fā)布,對外發(fā)布的API將會很難改變。
在給SupportedFu設(shè)計(jì)API的時候,我試圖以實(shí)用的角度來解決上面提到的問題。我希望可以設(shè)計(jì)出容易使用,容易部署,并且足夠靈活的API,本文因此而生。
API設(shè)計(jì)的基本要求
網(wǎng)上的很多關(guān)于API設(shè)計(jì)的觀點(diǎn)都十分”學(xué)院派“,它們也許更有理論基礎(chǔ),但是有時卻和現(xiàn)實(shí)世界脫軌(因此我是自由派)。所以我這篇文章的目標(biāo)是從實(shí)踐的角度出發(fā),給出當(dāng)前網(wǎng)絡(luò)應(yīng)用的API設(shè)計(jì)最佳實(shí)踐(當(dāng)然,是我認(rèn)為的最佳了~),如果覺得不合適,我不會遵從標(biāo)準(zhǔn)。當(dāng)然作為設(shè)計(jì)的基礎(chǔ),幾個必須的原則還是要遵守的:
當(dāng)標(biāo)準(zhǔn)合理的時候遵守標(biāo)準(zhǔn)。
API應(yīng)該對程序員友好,并且在瀏覽器地址欄容易輸入。
API應(yīng)該簡單,直觀,容易使用的同時優(yōu)雅。
API應(yīng)該具有足夠的靈活性來支持上層ui。
API設(shè)計(jì)權(quán)衡上述幾個原則。
需要強(qiáng)調(diào)的是:API的就是程序員的UI,和其他UI一樣,你必須仔細(xì)考慮它的用戶體驗(yàn)!
雖然前面我說沒有一個萬能的API設(shè)計(jì)標(biāo)準(zhǔn)。但確實(shí)有一個被普遍承認(rèn)和遵守:RESTfu設(shè)計(jì)原則。它被Roy Felding提出(在他的”基于網(wǎng)絡(luò)的軟件架構(gòu)“論文中第五章)。而REST的核心原則是將你的API拆分為邏輯上的資源。這些資源通過http被操作(GET ,POST,PUT,DELETE)。
那么我應(yīng)該如何拆分出這些資源呢?
顯然從API用戶的角度來看,”資源“應(yīng)該是個名詞。即使你的內(nèi)部數(shù)據(jù)模型和資源已經(jīng)有了很好的對應(yīng),API設(shè)計(jì)的時候你仍然不需要把它們一對一的都暴露出來。這里的關(guān)鍵是隱藏內(nèi)部資源,暴露必需的外部資源。
在SupportFu里,資源是 ticket、user、group。
一旦定義好了要暴露的資源,你可以定義資源上允許的操作,以及這些操作和你的API的對應(yīng)關(guān)系:
GET /tickets # 獲取ticket列表
GET /tickets/12 # 查看某個具體的ticket
POST /tickets # 新建一個ticket
PUT /tickets/12 # 更新ticket 12.
DELETE /tickets/12 #刪除ticekt 12
可以看出使用REST的好處在于可以充分利用http的強(qiáng)大實(shí)現(xiàn)對資源的CURD功能。而這里你只需要一個endpoint:/tickets,再沒有其他什么命名規(guī)則和url規(guī)則了,cool!
這個endpoint的單數(shù)復(fù)數(shù)
一個可以遵從的規(guī)則是:雖然看起來使用復(fù)數(shù)來描述某一個資源實(shí)例看起來別扭,但是統(tǒng)一所有的endpoint,使用復(fù)數(shù)使得你的URL更加規(guī)整。這讓API使用者更加容易理解,對開發(fā)者來說也更容易實(shí)現(xiàn)。
如何處理關(guān)聯(lián)?關(guān)于如何處理資源之間的管理REST原則也有相關(guān)的描述:
GET /tickets/12/messages- Retrieves list of messages for ticket #12
GET /tickets/12/messages/5- Retrieves message #5 for ticket #12
POST /tickets/12/messages- Creates a new message in ticket #12
PUT /tickets/12/messages/5- Updates message #5 for ticket #12
PATCH /tickets/12/messages/5- Partially updates message #5 for ticket #12
DELETE /tickets/12/messages/5- Deletes message #5 for ticket #12
其中,如果這種關(guān)聯(lián)和資源獨(dú)立,那么我們可以在資源的輸出表示中保存相應(yīng)資源的endpoint。然后API的使用者就可以通過點(diǎn)擊鏈接找到相關(guān)的資源。如果關(guān)聯(lián)和資源聯(lián)系緊密。資源的輸出表示就應(yīng)該直接保存相應(yīng)資源信息。(例如這里如果message資源是獨(dú)立存在的,那么上面 GET /tickets/12/messages就會返回相應(yīng)message的鏈接;相反的如果message不獨(dú)立存在,他和ticket依附存在,則上面的API調(diào)用返回直接返回message信息)
不符合CURD的操作
對這個令人困惑的問題,下面是一些解決方法:
重構(gòu)你的行為action。當(dāng)你的行為不需要參數(shù)的時候,你可以把a(bǔ)ctive對應(yīng)到activated這個資源,(更新使用patch)。
以子資源對待。例如:github上,對一個gists加星操作:PUT /gists/:id/star 并且取消星操作:DELETE /gists/:id/star.
有時候action實(shí)在沒有難以和某個資源對應(yīng)上例如search。那就這么辦吧。我認(rèn)為API的使用者對于/search這種url也不會有太大意見的(畢竟他很容易理解)。只要注意在文檔中寫清楚就可以了。
評論