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