App後臺開發運維和架構實踐學習總結(3)——RestFul架構下API接口設計注意點

1. 爭取相容性和統一性

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

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

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

2. 考慮得直爽些

你應該有過打電話給別人讓他幫你做一件事時對方很爽快地回覆一個“好!”的經歷吧?通常這時你會躊躇一下然後去問“你確定會幫我做吧?”。優秀的API不僅會做你想要它執行的操作而且還會額外返回有關它剛執行的操作的相關信息。如果你的某個API是負責創建一個product的,那麼就讓它執行完創建操作後返回一些有關剛剛創建的product的相關信息,而不是去要求客戶端再去發送一個請求來獲取你剛剛創建的product的相關信息。因爲那樣就顯得你很沒腦子。但是你還是會驚奇地發現有很多API執行完操作後只返回一點像200 OK那樣的信息。所以只需要讓你的API給客戶端返回一些有用而且明顯需要的關於剛剛執行的操作的相關信息就可以讓它變得直爽。

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

你通常是不是更願意這麼做:讓別人開車載你去幹洗店或者直接讓別人開車去幹洗店,下車後打開店門走進乾洗店,找店員拿完你的衣服然後離開乾洗店再開車回到你這兒。所以你的API不要讓客戶端調用多次只是爲了去做一個通常都需要執行的子任務!你可以通過提供默認參數值而且允許客戶端可以根據特定請求去覆蓋你的任意一個默認參數值來解決這個問題。

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

4. 恰當地使用響應

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

5. 多考慮性能問題

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

Chargify在這方面就做得很好。我向他們請求一個預定產品時他們能夠在200ms左右回覆我結果。這是相當快的。而且如果我在一分鐘之後再次請求這個預定產品時他們會在97ms內返回給我同樣的結果。同時要知道並不是所有的接口和查詢都可以像那樣設計,但是如果你的數據是不變的或者不經常變,那麼就要考慮在你的API使用緩存來加速請求的處理。你的客戶端將會因爲這愛上你。如果客戶端將響應結果緩存在它們自己的客戶端緩存裏那就能讓他們更滿意了。

6. 用帶有SSL的Basic 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是你的生意的話,那些錯誤會讓你整個生意黃掉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章