天天看點

一文搞懂RESTful API

原創公衆号:bigsai 轉載請聯系bigsai 文章收藏在回車課堂 和github

在學習RESTful 風格接口之前,即使你不知道它是什麼,但你肯定會好奇它能解決什麼問題?有什麼應用場景?聽完下面描述我想你就會明白:

在網際網路并沒有完全流行的初期,移動端也沒有那麼盛行,頁面請求和并發量也不高,那時候人們對接口的要求沒那麼高,一些動态頁面(jsp)就能滿足絕大多數的使用需求。

一文搞懂RESTful API

但是随着網際網路和移動裝置的發展,人們對Web應用的使用需求也增加,傳統的動态頁面由于低效率而漸漸被HTML+JavaScript(Ajax)的前後端分離所取代,并且安卓、IOS、小程式等形式用戶端層出不窮,用戶端的種類出現多元化,而用戶端和服務端就需要接口進行通信,但接口的規範性就又成了一個問題:

一文搞懂RESTful API

是以一套結構清晰、符合标準、易于了解、擴充友善讓大部分人都能夠了解接受的接口風格就顯得越來越重要,而RESTful風格的接口(RESTful API)剛好有以上特點,就逐漸被實踐應用而變得流行起來。

一文搞懂RESTful API

現在,RESTful是目前最流行的接口設計規範,在很多公司有着廣泛的應用,其中Github 的API設計就是很标準的RESTful API,你可以參考學習。

在開發實踐中我們很多人可能還是使用傳統API進行請求互動,很多人其實并不特别了解RESTful API,對RESTful API的認知可能會停留在:

面向資源類型的

是一種風格

(誤區)接口傳遞參數使用斜杠(/)分割而不用問号(?)傳參。

而其實一個很大的誤區不要認為沒有查詢字元串就是RESTful API,也不要認為用了查詢字元串就不是RESTful API,更不要認為用了JSON傳輸的API就是RESTful API。

本教程将帶你了解RESTful并用SpringBoot實戰RESTful API,在實作本案例前,你需要保證你的電腦上

擁有IDEA用來編寫項目代碼

擁有Postman模拟請求進行測試

擁有關系資料庫MySQL 5.7

擁有navicat對MySQL進行管理

REST涉及一些概念性的東西可能比較多,在實戰RESTful API之前,要對REST相關的知識有個系統的認知。

REST(英文:Representational State Transfer,簡稱REST,直譯過來表現層狀态轉換)是一種軟體架構風格、設計風格,而不是标準,隻是提供了一組設計原則和限制條件。它主要用于用戶端和伺服器互動類的軟體。基于這個風格設計的軟體可以更簡潔,更有層次,更易于實作緩存等機制。

它首次出現在 2000 年 Roy Thomas Fielding 的博士論文中,這篇論文定義并詳細介紹了表述性狀态轉移(Representational State Transfer,REST)的架構風格,并且描述了 如何使用 REST 來指導現代 Web 架構的設計和開發。用他自己的原話說:

我寫這篇文章的目的是:在符合架構原理前提下,了解和評估基于網絡的應用軟體的架構設計,得到一個功能強、性能好、适宜通信的架構。

需要注意的是REST并沒有一個明确的标準,而更像是一種設計的風格,滿足這種設計風格的程式或接口我們稱之為RESTful(從單詞字面來看就是一個形容詞)。是以RESTful API 就是滿足REST架構風格的接口。

一文搞懂RESTful API

Fielding博士當時提出的是REST架構在很久的時間内并沒有被關注太多,而近些年REST在國内才變得越來越流行。下面開始詳細學習REST架構特征。

既然知道REST和RESTful的聯系和差別,現在就要開始好好了解RESTful的一些限制條件和規則,RESTful是一種風格而不是标準,而這個風格大緻有以下幾個主要特征:

以資源為基礎 :資源可以是一個圖檔、音樂、一個XML格式、HTML格式或者JSON格式等網絡上的一個實體,除了一些二進制的資源外普通的文本資源更多以JSON為載體、面向使用者的一組資料(通常從資料庫中查詢而得到)。

統一接口: 對資源的操作包括擷取、建立、修改和删除,這些操作正好對應HTTP協定提供的GET、POST、PUT和DELETE方法。換言而知,使用RESTful風格的接口但從接口上你可能隻能定位其資源,但是無法知曉它具體進行了什麼操作,需要具體了解其發生了什麼操作動作要從其HTTP請求方法類型上進行判斷。具體的HTTP方法和方法含義如下:

GET(SELECT):從伺服器取出資源(一項或多項)。

POST(CREATE):在伺服器建立一個資源。

PUT(UPDATE):在伺服器更新資源(用戶端提供完整資源資料)。

PATCH(UPDATE):在伺服器更新資源(用戶端提供需要修改的資源資料)。

DELETE(DELETE):從伺服器删除資源。

當然也有很多在具體使用的時候使用PUT表示更新。從請求的流程來看,RESTful API和傳統API大緻架構如下:

一文搞懂RESTful API

URI指向資源:URI = Universal Resource Identifier 統一資源标志符,用來辨別抽象或實體資源的一個緊湊字元串。URI包括URL和URN,在這裡更多時候可能代指URL(統一資源定位符)。RESTful是面向資源的,每種資源可能由一個或多個URI對應,但一個URI隻指向一種資源。

無狀态:伺服器不能儲存用戶端的資訊, 每一次從用戶端發送的請求中,要包含所有必須的狀态資訊,會話資訊由用戶端儲存, 伺服器端根據這些狀态資訊來處理請求。 當用戶端可以切換到一個新狀态的時候發送請求資訊, 當一個或者多個請求被發送之後, 用戶端就處于一個狀态變遷過程中。 每一個應用的狀态描述可以被用戶端用來初始化下一次的狀态變遷。

Fielding在論文中提出REST架構的6個限制條件,也可稱為RESTful 6大原則, 标準的REST限制應滿足以下6個原則:

用戶端-服務端(Client-Server): 這個更專注用戶端和服務端的分離,服務端獨立可更好服務于前端、安卓、IOS等用戶端裝置。

無狀态(Stateless):服務端不儲存用戶端狀态,用戶端儲存狀态資訊每次請求攜帶狀态資訊。

可緩存性(Cacheability) :服務端需回複是否可以緩存以讓用戶端甄别是否緩存提高效率。

統一接口(Uniform Interface):通過一定原則設計接口降低耦合,簡化系統架構,這是RESTful設計的基本出發點。當然這個内容除了上述特點提到部分具體内容比較多詳細了解可以參考這篇REST論文内容。

分層系統(Layered System):用戶端無法直接知道連接配接的到終端還是中間裝置,分層允許你靈活的部署服務端項目。

按需代碼(Code-On-Demand,可選):按需代碼允許我們靈活的發送一些看似特殊的代碼給用戶端例如JavaScript代碼。

REST架構的一些風格和限制條件就先介紹到這裡,後面就對RESTful風格API具體介紹。

既然了解了RESTful的一些規則和特性,那麼具體該怎麼去設計一個RESTful API呢?要從URL路徑、HTTP請求動詞、狀态碼和傳回結果等方面詳細考慮。至于其他的方面例如錯誤處理、過濾資訊等規範這裡就不詳細介紹了。

URL為統一資源定位器 ,接口屬于服務端資源,首先要通過URL這個定位到資源才能去通路,而通常一個完整的URL組成由以下幾個部分構成:

scheme: 指底層用的協定,如http、https、ftp

host: 伺服器的IP位址或者域名

port: 端口,http預設為80端口

path: 通路資源的路徑,就是各種web 架構中定義的route路由

query: 查詢字元串,為發送給伺服器的參數,在這裡更多發送資料分頁、排序等參數。

fragment: 錨點,定位到頁面的資源

我們在設計API時URL的path是需要認真考慮的,而RESTful對path的設計做了一些規範,通常一個RESTful API的path組成如下:

version:API版本号,有些版本号放置在頭資訊中也可以,通過控制版本号有利于應用疊代。

resources:資源,RESTful API推薦用小寫英文單詞的複數形式。

resource_id:資源的id,通路或操作該資源。

當然,有時候可能資源級别較大,其下還可細分很多子資源也可以靈活設計URL的path,例如:

此外,有時可能增删改查無法滿足業務要求,可以在URL末尾加上action,例如

其中action就是對資源的操作。

從大體樣式了解URL路徑組成之後,對于RESTful API的URL具體設計的規範如下:

不用大寫字母,所有單詞使用英文且小寫。

連字元用中杠<code>"-"</code>而不用下杠<code>"_"</code>

正确使用 <code>"/"</code>表示層級關系,URL的層級不要過深,并且越靠前的層級應該相對越穩定

結尾不要包含正斜杠分隔符<code>"/"</code>

URL中不出現動詞,用請求方式表示動作

資源表示用複數不要用單數

不要使用檔案擴充名

在RESTful API中,不同的HTTP請求方法有各自的含義,這裡就展示GET,POST,PUT,DELETE幾種請求API的設計與含義分析。針對不同操作,具體的含義如下:

在非RESTful風格的API中,我們通常使用GET請求和POST請求完成增删改查以及其他操作,查詢和删除一般使用GET方式請求,更新和插入一般使用POST請求。從請求方式上無法知道API具體是幹嘛的,所有在URL上都會有操作的動詞來表示API進行的動作,例如:query,add,update,delete等等。

而RESTful風格的API則要求在URL上都以名詞的方式出現,從幾種請求方式上就可以看出想要進行的操作,這點與非RESTful風格的API形成鮮明對比。

在談及GET,POST,PUT,DELETE的時候,就必須提一下接口的安全性和幂等性,其中安全性是指方法不會修改資源狀态,即讀的為安全的,寫的操作為非安全的。而幂等性的意思是操作一次和操作多次的最終效果相同,用戶端重複調用也隻傳回同一個結果。

上述四個HTTP請求方法的安全性和幂等性如下:

HTTP Method

安全性

幂等性

解釋

GET

安全

幂等

讀操作安全,查詢一次多次結果一緻

POST

非安全

非幂等

寫操作非安全,每多插入一次都會出現新結果

PUT

寫操作非安全,一次和多次更新結果一緻

DELETE

寫操作非安全,一次和多次删除結果一緻

服務端處理完成後用戶端也可能不知道具體成功了還是失敗了,伺服器響應時,包含狀态碼和傳回資料兩個部分。

狀态碼

我們首先要正确使用各類狀态碼來表示該請求的處理執行結果。狀态碼主要分為五大類:

1xx:相關資訊 2xx:操作成功 3xx:重定向 4xx:用戶端錯誤 5xx:伺服器錯誤

每一大類有若幹小類,狀态碼的種類比較多,而主要常用狀态碼羅列在下面:

200 <code>OK - [GET]</code>:伺服器成功傳回使用者請求的資料,該操作是幂等的(Idempotent)。

201 <code>CREATED - [POST/PUT/PATCH]</code>:使用者建立或修改資料成功。

202 <code>Accepted - [*]</code>:表示一個請求已經進入背景排隊(異步任務)

204 <code>NO CONTENT - [DELETE]</code>:使用者删除資料成功。

400 <code>INVALID REQUEST - [POST/PUT/PATCH]</code>:使用者發出的請求有錯誤,伺服器沒有進行建立或修改資料的操作,該操作是幂等的。

401 <code>Unauthorized - [*]</code>:表示使用者沒有權限(令牌、使用者名、密碼錯誤)。

403 <code>Forbidden - [*]</code> 表示使用者得到授權(與401錯誤相對),但是通路是被禁止的。

404 <code>NOT FOUND - [*]</code>:使用者發出的請求針對的是不存在的記錄,伺服器沒有進行操作,該操作是幂等的。

406 <code>Not Acceptable - [GET]</code>:使用者請求的格式不可得(比如使用者請求JSON格式,但是隻有XML格式)。

410 <code>Gone -[GET]</code>:使用者請求的資源被永久删除,且不會再得到的。

422 <code>Unprocesable entity - [POST/PUT/PATCH]</code> 當建立一個對象時,發生一個驗證錯誤。

500 <code>INTERNAL SERVER ERROR - [*]</code>:伺服器發生錯誤,使用者将無法判斷發出的請求是否成功。

傳回結果

針對不同操作,伺服器向使用者傳回資料,而各個團隊或公司封裝的傳回實體類也不同,但都傳回JSON格式資料給用戶端。

上面講了RESTful理論知識,下面動手實作一個小案例吧!

在本案例的實戰中,我們通路的RESTful接口都是對資料庫真實的操作,建立資料庫,建立一個資料庫和表(根據自己喜好)。

選擇Maven依賴的時候,隻需要勾選其中Spring的Web子產品、MySQL驅動以及MyBatis架構。

本案例的POJO建立Dog.java實體對象,其具體構造為:

上面建立好了項目,我們就開始建構RESTful風格的API。在具體建構RESTful API的時候,需要對各種請求有更細緻的認知,當然,本案例在實作各種請求的時候為了示範的便捷并沒有完全遵循RESTful API規範,例如版本号等資訊這裡就不添加了,案例更側重于使用SpringBoot實作這個接口。

本案例實作對dog資源的增删改查,如下是非RESTful 和RESTful接口對比:

API name

非 RESTful

RESTful

擷取dog

<code>/dogs/query/{dogid}</code>

GET: <code>/dogs/{dogid</code>}

插入dog

<code>/dogs/add</code>

POST: <code>/dogs</code>

更新dog

<code>/dogs/update/{dogid}</code>

PUT:<code>/dogs/{dogid}</code>

删除dog

<code>/dods/delete/{dogid}</code>

DELETE:<code>/dogs/{dogid}</code>

另外在使用postman進行發送請求的時候,有三種常用的檔案類型傳遞到後端:

一文搞懂RESTful API

form-data : 就是form表單中的multipart/form-data,會将表單資料處理為一條資訊,用特定标簽符将一條條資訊分割開,而這個檔案類型通常用來上傳二進制檔案。

x-www-form-urlencoded:就是application/x-www-form-urlencoded,是form表單預設的encType,form表單會将表單内的資料轉換為鍵值對,這種格式不能上傳檔案。

raw:可以上傳任意格式的文本,可以上傳Text,JSON,XML等,但目前大部分還是上傳JSON格式資料。當後端需要接收JSON格式資料處理的時候,可以采用這種格式來測試。

因為GET請求查詢參數在URL上,其他類型請求使用x-www-form-urlencoded方式向後端傳值。

GET請求用來擷取資源:GET請求會向資料庫發索取資料的請求,進而來擷取資源,該請求就像資料庫的select操作一樣,隻是用來查詢資料,不會影響資源的内容。無論進行多少次操作,結果都是一樣的。

并且GET請求會把請求的參數附加在URL後面,但是不同的浏覽器對其有不同的大小長度限制。

在本案例中,我們設計兩個GET請求的API。

<code>GET /dogs</code> :用來傳回dog資源的清單。

<code>GET /dogs/{dogid}</code> :用來查詢此id的單個dog資源。

POST請求用來新增一個資源 : POST請求向伺服器發送資料,但是該請求會改變資料的内容(新添),就像資料庫的<code>insert</code>操作一樣,會建立新的内容。且POST請求的請求參數都是請求體中,其大小是沒有限制的。

在本案例中,我們設計以下POST請求的API。

<code>POST /dogs</code> :服務端新增一個dog資源。

PUT請求用來更新資源,PUT請求是向伺服器端發送資料的, 與POST請求不同的是,PUT請求側重于資料的修改 ,就像資料庫中update一樣,而POST請求側重于資料的增加。

<code>PUT /dogs/{dogid}</code> :用來更新此id的單個dog資源。

DELETE 請求用來删除資源,DELETE請求用途和它字面意思一緻,用來删除資源。和資料庫中delete相對應。

在本案例中,我們設計以下DELETE請求的API。

<code>DELETE /dogs/{dogid}</code> :用來删除此id的單個dog資源。

對應的Mapper檔案為:

對應controller檔案為:

經過筆者測試一切都是ok的,如果要項目源檔案請聯系筆者發你哈!

RESTful風格的API 固然很好很規範,但大多數網際網路公司并沒有按照或者完全按照其規則來設計,因為REST是一種風格,而不是一種限制或規則,過于理想的RESTful API 會付出太多的成本。

比如RESTful API也有一些缺點

比如操作方式繁瑣,RESTful API通常根據GET、POST、PUT、DELETE 來區分操作資源的動作,而HTTP Method 本身不可直接見,是隐藏的,而如果将動作放到URL的path上反而清晰可見,更利于團隊的了解和交流。

并且有些浏覽器對GET,POST之外的請求支援不太友好,還需要特殊額外的處理。

過分強調資源,而實際業務API可能有各種需求比較複雜,單單使用資源的增删改查可能并不能有效滿足使用需求,強行使用RESTful風格API隻會增加開發難度和成本。

是以,當你或你們的技術團隊在設計API的時候,如果使用場景和REST風格很比對,那麼你們可以采用RESTful 風格API。但是如果業務需求和RESTful風格API不太比對或者很麻煩,那也可以不用RESTful風格API或者可以借鑒一下,畢竟無論那種風格的API都是為了友善團隊開發、協商以及管理,不能墨守成規。

一文搞懂RESTful API

到這裡RESTful API的介紹和實戰就結束啦,本篇首先從RESTful的一些特點進行介紹,再到SpringBoot實戰RESTful API,最後也說了一些RESTful API并不完美的地方,相信睿智的你對RESTful 一定有了很深刻的了解。在以後項目的API設計上定能有所優化。

不同的人對RESTful API可能有着不同的了解,但存在即合理,RESTful API有着其鮮明的優勢和特點,目前也是一種API設計的主要選型之一,是以掌握和了解RESTful API還是相當重要的!

一文搞懂RESTful API

原創不易,bigsai我請你幫兩件事幫忙一下:

star支援一下, 您的肯定是我在平台創作的源源動力。

微信搜尋「bigsai」,關注我的公衆号,不僅免費送你電子書,我還會第一時間在公衆号分享知識技術。加我還可拉你進力扣打卡群一起打卡LeetCode。

記得關注、咱們下次再見!

一文搞懂RESTful API

繼續閱讀