優秀的Restful API應該是什么樣的


1 你一直在錯誤的使用http協議

 

現在微服務真是火的一塌糊塗!大街小巷,逢人必談微服務,各路大神紛紛忙着把自家的單體服務拆解成多個Web微小服務!而作為微服務之間通信的橋梁,Web API的設計就顯得非常重要。

 

Http是目前互聯網使用最多的協議,沒有之一!但是作為Http協議創始人之一的Roy Fielding認為,過去十年,大家都在錯誤的使用Http協議。刪除一個數據,路徑往往是 delete/{id} , 更新一條數據,路徑往往被定義為update/{id}。你已經被Roy在心里默默的鄙視了!

 

Roy Fielding提出了一種用於設計Web服務的架構方法,稱為Representational State Transfer(REST)。REST的概念是將API結構分離為操作和資源。使用HTTP方法GET、DELETE、POST和PUT操作資源。

 

設計糟糕的REST API = 浪費時間!

 

優秀的API就像一位藝術家在舞台上表演,其用戶就是觀眾,能給所有人帶來賞心悅目的美感!

 

 

2 REST API里面的術語

 

 

Resource(資源)是指代表某種東西的對象,它具有一些與之相關的數據,並且可以有一組方法對其進行操作。 例如。 學校,班級和學生是資源,刪除,添加,更新是要對這些資源執行的操作。

 

Collections(集合)是一組資源,例如,211大學是全國211所優質大學的集合。

 

URL(統一資源定位符)是可以通過其定位資源的路徑,並且可以對其執行某些操作。

 

 

3 API設計使用名詞,而不是動詞

 

 

例如獲取所有學生,可能通過如下api: 

/getAllStudents,

增加學生,可能是:/addNewStudent

更新學生,可能是:/updateStudent

刪除學生,可能是:/deleteStudent

刪除所有學生,可能是:/deleteStudents

獲取三好學生,可能是:/getSanHaoStudents

更多操作......等等。

 

對於不同的操作,會衍生出越來越多的API接口,數量不停的增多,接口將會變得混亂和難以維護。

 

有沒有感覺哪里不對?

URL應僅包含資源(名詞)而不包含動作或者動詞!增加學生的API路徑:/addNewStudent,包含操作addNew以及資源名稱Student。

 

正確的方法是什么?

 

/schools ,是一個很好的例子,不包含任何動作。但是我們怎么告訴服務器,有關學校資源的操作呢,例如增加,刪除或者更新學校?

 

這就是HTTP方法(GET,POST,DELETE,PUT)(也成為動詞)扮角色的地方!API接口的資源應始終為復數,如果我們要訪問資源的一個實例,我們可以在URL中傳遞id或者name之類的。

 

GET 路徑 /schools 獲取所有的學校

GET 路徑 /schools/清華 獲取名字叫清華大學的詳細信息

DELETE 路徑 /schools/清華 從學校列表中,刪除清華大學

 

資源和資源之間可能有父子關系,那又應該如何設計呢?例如學校的學生,下面是一些示例:

 

GET /schools/清華/students  獲取清華大學的所有學生

GET /schools/清華/students/張三 獲取清華大學名字叫張三的學生的詳細信息

DELETE /schools/清華/students/張三 刪除清華大學名字叫張三的學生

 

 

4 合理利用Http本身的方法

 

 

HTTP已定義了幾組方法,這些方法指示要對資源執行什么類型的操作。我們制定web接口,要合理利用http的方法!

 

URL是說白了,就是一個句子,其中資源是名詞,HTTP方法是動詞。

 

GET 方法從資源請求數據,不應產生任何其他作用。

例如/schools/清華/students,返回所有清華大學的學生

 

POST方法請求服務器在數據庫中創建資源,主要是在提交Web表單時。

/schools/清華/students/張三,在清華大學的學生資源,新增一個張三的學生。

POST是非冪等的,這意味着多個請求將具有不同的效果。

 

PUT方法請求服務器更新資源或創建資源(如果不存在)。

/schools/清華/students/張三, 對清華大學下的學生資源中,更新或者創建張三。

PUT是冪等的,這意味着多個請求將具有相同的效果。

 

DELETE方法請求從數據庫中刪除資源或其實例。

/schools/清華/students/張三,從清華大學的學生集合中,刪除學生張三的資源。

 

 

5 使用JSON作為通信格式

 

 

JSON閱讀性更高,擴展性更強,適合各種環境和語言進行解析,現在大的互聯網公司,對外提供的API基本都使用JSON。

 

6 使用HTTP狀態碼

 

 

當客戶端通過API向服務器發出請求時,客戶端應該知道反饋,無論是失敗,成功還是請求錯誤。 HTTP狀態代碼是一系列標准化代碼,針對http請求的可能會發生的各種情況。 服務器應始終返回正確的狀態代碼。

 

很多人喜歡把錯誤信息放在返回值中,典型的Code和Message,其實比較Low。

 

下面是Http狀態碼,可以合理利用處理各種請求反饋,將http自身的錯誤和服務器內部的錯誤,有一個很好的區分。

 

2xx(成功類別)

200 Ok表示GET,PUT或POST成功的標准HTTP響應。

201 Created每當創建新實例時,都應返回此狀態代碼。 例如,使用POST方法創建新實例時,應始返回201狀態代碼。

204 No Content表示請求已成功處理,但未返回任何內容。

 

3xx(重定向類別)

304 Not Modified表示客戶端已在其緩存中有響應。 因此無需再次傳輸相同的數據。

 

4xx(客戶端錯誤類別)

這些狀態代碼表示客戶端已提出錯誤請求。

400 Bad Request表示未處理客戶端的請求,因為服務器無法理解客戶端要求的內容。

401 Unauthorized表示不允許客戶端訪問資源,並應使用所需憑據重新請求。

403 Forbidden表示請求有效且客戶端已通過身份驗證,但不允許客戶端出於任何原因訪問該頁面或資源。例如,有時不允許授權客戶端訪問服務器上的目錄。

404 Not Found表示請求的資源現在不可用。

410 Gone表示已移動的請求資源不再可用。

 

5xx(服務器錯誤類別)

500內部服務器錯誤表示請求有效,但服務器完全混淆,並要求服務器提供某些意外情況。

503 Service Unavailable表示服務器已關閉或無法接收和處理請求。大多數情況下,例如服務器正在進行維護。

 

 

7 搜索,排序,過濾和分頁

 

 

所有這些操作都只是對一個數據集的查詢。將不會有新的API集來處理這些操作。我們需要使用GET方法API附加查詢參數。

下面看幾個例子:

GET /schools ? search = 清華大學 在大學集合中,搜索清華大學

GET /schools ? sort = rank_asc 按照升序排列學校

GET /schools ? location = 北京 按照城市對學校過濾

GET /schools ? page=6 獲取第六頁的學校列表

 

 

8 使用版本控制

 

 

例如下面兩個版本地址:

http://api.yourservice.com/v1/schools/清華

http://api.yourservice.com/v2/schools/清華

 

在API上加入版本信息可以有效的使用戶訪問正確的API,v2是新開發功能,開發階段,讓所有用戶訪問v1,等開發完成統一切到v2。

 

可以有效的跨版本訪問,例如在v2版本,還需要訪問v1版本的一些接口

 

 

9 總結

 

 

1,API接口都用小寫

2,使用JSON通信

3,API帶版本控制,比如v1,v2

4,使用Token令牌進行鑒權

5,路徑中單詞連接使用中划線-

6,使用HTTP自身的方法表示增刪改查資源, GET:查詢,POST:新增,PUT:更新,DELETE:刪除

7,合理使用HTTP狀態碼,200,201,400,401,403,500。比如401表示用戶身份認證失敗,403表示你驗證身份通過了,但是無權限操作資源。

 

在此,祝大家設計出優秀的Restful API!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM