對於API接口設計的幾點見解

我已經看過不少API設計相關的文章和優秀的REST API設計教程。他們一般討論的是適當的編碼技巧和如何在給定的語言中暴露接口。儘管那些是頗有用也是很須要的,可是他們常常忽略了一些能讓API工做得更好的想法。在這篇文章中我將給出已經在API服務公司的項目中實踐的8條建議,但願你能在你接下來的項目中能使用到。數據庫

1. 爭取相容性和統一性api

這裏就要求讓API設計得是可預測的。按照這種方式寫出全部接口和接口所須要的參數。如今就要確保命名是一致的,接口所需的參數順序也是一致的。你如今應該有products,orders和customers的數據吧?,它們應該都存在含有id和name的表中。那麼不要讓一個接口僅傳ID而另外一個僅傳name還有的兩個都要傳。也不要讓一個接口按照/product/ID傳參而另外一個接口按/ID/customer這樣傳參。由於做爲一個API的使用者我但願以相同的方式訪問兩個不一樣的資源。緩存

另一個保證相容性的技巧是觀察你的參數值類型。若是一個接口的ID參數求爲整型,那麼不要讓另外一個接口的ID參數爲字符串型。由於做爲一個API的使用者我不想去猜每一個接口的每一個參數值類型。安全

除了須要考慮你的接口如何訪問數據之外,你也應該好好想一下你的API如何返回數據以及返回數據格式的統一性。目前在我最近使用的API中就存在一個很大的問題。當開發中用到一個返回數據的接口時,我很驚奇的發現返回結果(XML格式的...我接下來會討論爲何我將會避免使用它)裏面的每一個元素都本該都含有一個特定的屬性。然而結果是一些元素有那個屬性而另外一些卻沒有。我寧願那個屬性是一個空值也不肯意看到徹底沒有那個屬性。緣由是若是我遍歷每一個元素來尋找這個屬性,我但願至少能找到它,即便它沒有值。然而如今就像是從數據庫查出幾條記錄而後發現有幾條數據裏面沒有某個字段而其餘幾條卻有。而後這就開始讓你懷疑查詢出來的結果併產生了一個疑問「那些消失的屬性是被我弄丟的嗎?」服務器

2. 考慮得直爽些restful

你應該有過打電話給別人讓他幫你作一件事時對方很爽快地回覆一個「好!」的經歷吧?一般這時你會躊躇一下而後去問「你肯定會幫我作吧?」。優秀的API不只會作你想要它執行的操做並且還會額外返回有關它剛執行的操做的相關信息。若是你的某個API是負責建立一個product的,那麼就讓它執行完建立操做後返回一些有關剛剛建立的product的相關信息,而不是去要求客戶端再去發送一個請求來獲取你剛剛建立的product的相關信息。由於那樣就顯得你很沒腦子。可是你仍是會驚奇地發現有不少API執行完操做後只返回一點像200 OK那樣的信息。因此只須要讓你的API給客戶端返回一些有用並且明顯須要的關於剛剛執行的操做的相關信息就可讓它變得直爽。性能

3. API很容易去完成一個請求編碼

你一般是否是更願意這麼作:讓別人開車載你去幹洗店或者直接讓別人開車去幹洗店,下車後打開店門走進乾洗店,找店員拿完你的衣服而後離開乾洗店再開車回到你這兒。因此你的API不要讓客戶端調用屢次只是爲了去作一個一般都須要執行的子任務!你能夠經過提供默認參數值並且容許客戶端能夠根據特定請求去覆蓋你的任意一個默認參數值來解決這個問題。設計

我目前一直在用的一個API就讓我感到很痛苦並且還很費事時。它本應該設計成只需一個簡單的請求就能夠建立一個預約產品,並且耗時只須要耗時300-500ms,然而它卻設計成須要你去發送7個往返都須要300-500ms的請求。這便使得原本只要300-500ms的進程要花費好幾秒!並且這些增長的時間都會被使用這個API預約產品的消費者注意到。rest

4. 恰當地使用響應

這條建議是創建在前幾條之上的。若是請求的操做處理成功了,返回了一個成功像200 OK這樣的狀態碼。若是請求的操做處理失敗了,給出適當的像404或500等這樣的狀態碼來代表處理失敗了。由於咱們想要實現的是客戶端在使用API時首先能根據返回的狀態碼來決定接來下如何去處理具體的返回內容。我如今用的一個API確實是會返回給我一個200 OK的狀態碼可是他緊接的返回內容是一個處理失敗的報錯信息。以致於,儘管我知道請求成功了可是我不得不去檢查我請求的操做是否真的處理成功了。因此請不要像這樣設計。你只須要在一開始就返回一個恰當的狀態碼後接下來就知道該如何處理了。

5. 多考慮性能問題

優秀的API都是可以很快地處理大量的請求。你處理完一個請求後取得的結果能夠直接返回給那些徹底相同的請求而不須要重複處理。換句話說,你應該儘量地使用像服務器端緩存那樣的技術。若是一個用戶請求product1的信息,而後過幾秒又有另外一我的也請求product1的信息,這時你就能夠將返回給第一次請求的結果一樣返回給後來的請求。不須要再次查詢僅僅是爲了返回你剛纔已經查出來過的相同數據。同時也要確保給緩存一個過時時間以避免讓緩存內容變得過期。

Chargify在這方面就作得很好。我向他們請求一個預約產品時他們可以在200ms左右回覆我結果。這是至關快的。並且若是我在一分鐘以後再次請求這個預約產品時他們會在97ms內返回給我一樣的結果。同時要知道並非全部的接口和查詢均可以像那樣設計,可是若是你的數據是不變的或者不常常變,那麼就要考慮在你的API使用緩存來加速請求的處理。你的客戶端將會由於這愛上你。若是客戶端將響應結果緩存在它們本身的客戶端緩存裏那就能讓他們更滿意了。

6. 用帶有SSLBasic Auth

你如今有不少種方法來保障API的安全性,例如:Basic Auth(基本認證),Digest Auth(摘要認證 ),OAuth(開放認證),no auth等。當你考慮用哪一種方法的時候須要考慮的是認證方法的性能和易用性(像上面的建議5和建議3所說的)。若是你用了SSL的話,我建議你採用Basic Auth方法,由於它很容易部署,並且只須要請求一次而不須要屢次(Digest Auth一般都須要至少兩次以上的請求才能完成認證)因此性能相對來講也會高些。顯然若是你不使用SSL,那麼就建議你用Digest Auth或者OAuth等其餘的安全的認證方法。

7. 給你的API制定版本

恭喜你!你的API設計的很成功並且在被不少用戶使用。如今他們的不少產品和項目開始依賴於你的API。可是你如今須要考慮的是如何在不影響他們使用的狀況下去更新你的API。若是你能讓不一樣版本的API相互獨立開來,我建議你將版本號做爲一個參數或者API命名的一部分。例如:GET /v1/product/id或者 GET /v2/product/id 或者 GET /product/id?v=1。你也能夠選擇將版本號部署進HTTP請求頭,可是不管你採用哪一種方法都要確保全部的版本都採用同一種方法。

經過將API用版本號區分開可讓用戶一直使用某個版本的API直到恰當的時候再遷移到新版的API。你也能夠隨時關掉某個版本API而不須要對現有版本的API作任何處理。

8. 使用JSON而不要使用XML

第8條建議是根據我我的偏好提出的。我工做到如今用過不少API,JSON格式和XML格式都有。我會告訴你我以爲JSON格式的更好用。JSON格式一般是更爲簡潔的(以致於傳輸的數據量更小),也更容易展示覆雜的對象(精確)並且能運行得像其餘格式同樣好(以致於如今每一個人都在用JSON)。XML一般都是很冗餘的,還不容易展示覆雜的元素並且還須要一個DTD來驗證它。因此我將會用JSON格式,若是你想用XML的話那就隨便吧。無論怎樣,我認爲只要你開始用JSON你就會很明顯得發現XML的缺點。

總結

我提出的8條建議能夠幫你更好地考慮你接下來須要設計的API。API正在改變咱們和集成系統的交互方式,因此它的質量就變得尤其重要了。若是你設計API時考慮到了終端用戶,那麼你就要考慮如何讓他們更容易使用,這樣你的API纔會變得更成功。若是用戶用別的API也能完成你的API能完成的事,可是別人的API更容易使用、響應速度更快,用戶天然就會去用別人的而不是你的。

因此不要犯這些嚴重的錯誤:傳參格式不一致,只作簡單的響應,對剛剛處理的結果隻字不提(不健談)並且響應得很慢。那將毀了你整個API。若是你的API是你的生意的話,那些錯誤會讓你整個生意黃掉。

相關文章
相關標籤/搜索