賀!此系列文榮獲 2023 iThome 鐵人賽《優選》獎項,正在規劃出書中,感謝大家的支持🙏,同名課程「Java 工程師必備!Spring Boot 零基礎入門」也已在 Hahow 平台上架
哈囉大家好,我是古古
在前幾篇文章中,有分別去介紹了 Spring Boot 中取得前端參數的四個註解,因此大家就可以去根據不同的情境,使用不同的註解來取得前端傳遞過來的參數
而接著這篇文章,會來融合前面所學的知識,介紹在開發網頁程式時,一個非常常見的風格,也就是「RESTful API」,所以我們就開始吧!
在開始介紹「RESTful API」之前,大家需要先了解什麼是「API」,因此我們就先來簡單介紹一下,到底什麼是 API
API 是指「用工程師的方式,去說明某個功能的使用方法」,所以換句話說的話,其實就是用特定的格式,去表示某個功能到底要怎麼使用啦,等於是一個使用說明書的概念
譬如說以「取得商品列表」這個功能為例,當我們在 Spring Boot 程式中寫好這個功能,想要開放給前端或是其他人使用時,我們總不可能直接把 Spring Boot 程式貼給對方看,因為對方可能不熟悉 Spring Boot、或是他根本不了解 Java 程式語言,因此這樣子會造成溝通效率低落
而為了解決這個問題,就有了 API 的出現!
API 的目的,就是「用工程師看得懂的方式,去說明某個方法要如何使用」,譬如說像是下面這例子,我們就把「取得商品列表」的 API 給定義好了,像是我們會去說明要使用 GET
方法來請求、並且請求參數 (query parameter) 要帶上什麼、以及可能的 Http response 回覆會是什麼
而當前端拿到這樣子一個定義清楚的 API 的時候,他就能夠照著上面的介紹,去決定他在發起一個 Http request 時,到底需要使用哪個 Http method(GET 還是 POST)、或是 url 路徑是多少,以及他最後可能得到的返回結果又是什麼
因此透過 API 的設計,就可以更清楚明瞭的去知道某個功能的使用方式,進而提升前後端溝通的效率!
了解了 API 的概念之後,接著就可以來介紹什麼是「RESTful API」了!
其實「RESTful API」的意思,就是去設計出一套「符合 REST 風格的 API」,換句話說的話,就是在設計 API 的時候,去套用 REST 風格就對了
在英文的文法裡面,有一種用法,就是在字尾加個 ful
,就可以把名詞轉成形容詞
因此 REST 是一個名詞,表示「REST 風格」,而 RESTful 就是形容詞,表示「REST 風格的」
所以 RESTful API 的意思,就是表示「這個 API 是很 REST 風格的」而已,因此大家之後看到 RESTful 和 REST 時,就不會再傻傻分不清楚了XD,他們就只是在玩英文文法而已
大概了解 RESTful 和 REST 的差別之後,我們可以說回到一開始的 RESTful API 上
所以大家現在知道,RESTful API 就是「符合 REST 風格的 API」,因此要設計出這樣子的 API,重點就是要讓你的 API「很 REST 風格」
而如果想要讓你所設計的 API 符合 REST 風格,就會需要符合三項特點
首先第一點,就是 RESTful API 會使用「Http method 來表示一個動作」,即是賦予了 Http method 更多的意義
REST 風格會把 POST、GET、PUT、DELETE 這四種 Http method,分別去對應到資料庫的 Create、Read、Update、Delete 操作上
所以假設你的 API 是 RESTful API,那麼當某隻 API 是使用 GET
來請求時,那就是在暗示這個 API 是會去資料庫中進行「Read 查詢」的動作,也就是會去查一筆數據出來
而如果另一隻 API 是使用 POST
來請求時,那就是在暗示那隻 API 是會去資料庫中進行「Create 新增」的動作,也就是會在資料庫中創建一筆新的數據出來
因此在 RESTful API 的世界裡面,Http method 影響的不僅僅是 GET、POST 這些請求參數的傳遞而已,也是在「暗示」這隻 API 後續會去執行資料庫的哪些操作
所以假設大家想要設計去 RESTful API,那麼第一步,就是重新思考每個 API 該使用的 Http method 為何
而也透過這樣子的方式,所以其他工程師就可以更快透過 Http method,來快速判斷這個 API 可能執行的資料庫操作為何(譬如說你看到 GET 的 API,就大概知道「哦他是要去查數據啦」這樣)
RESTful API 的第二項特徵,就是會「使用 url 路徑,來描述資源之間的階層關係」
在 REST 風格裡面,url 路徑代表的是「每個資源之間的階層關係」,這個聽起來可能有點抽象,我們可以直接透過一個例子,來了解什麼是資源之間的階層關係
假設現在有一個 API GET /users
,那根據我們剛剛所介紹的 REST 風格,知道 GET 是去對應到資料庫的「Read 查詢」操作,因此這個 API GET /users
的含義,就是去「取得所有的 user」
那假設我們又有另一個 API GET /users/123
,這個 API 的含義,就是去「取得在所有的 user 裡面,user id 為 123 的那個 user」
到這邊,REST 風格的階層概念就出現了!
大家可以想像一下,在 url 路徑裡面的每出現一個斜線 /
,他就表示是一個階層,也就是一個子集合的感覺,或是換句話說的話,也是可以直接把斜線替換成中文的「的」
所以像是上面的 GET /users
,就表示要取得的是「所有的 user」,而下面的 GET /users/123
,代表的則是要「取得所有 user 裡面,id 為 123 的那個 user」,是一個子集合的概念
所以在 REST 風格裡面,我們就可以去透過 url 路徑,來表達我們想要取得的資源是什麼,以及他和其他資源的階層關係了!
下面也提供更多例子給大家,讓大家感受一下在 REST 風格中,url 路徑所表示的階層關係
所以假設大家想要設計去 RESTful API,那麼第二步,重新思考 url 路徑的設計,因為 REST 風格對 url 路徑的寫法是有要求的,必須寫成上面這種階層的寫法才可以
而如果你的 API 有照著這樣子的階層寫法來設計 url 路徑的話,那麼其他的工程師就可以直接透過 url 路徑,來了解這個 API 要操作的資源,和其他資源的之間的階層關係了(等於也是一個潛規則的暗示就對了)
滿足 RESTful API 的最後一個條件比較簡單,就是 REST 風格會要求後端程式所回傳的 response body,必須要是 Json 或是 Xml 的格式
補充:雖然目前在 response body 中回傳 Json 格式比較普遍,但是其實使用 Xml 格式來回傳,也是符合 REST 風格的
關於如何將 Spring Boot 程式的返回值改成 Json 格式,這部分我們在 Day 17 - 返回值改成 Json 格式 - @RestController 那篇文章中,因此如果有需要的話,可以回頭參考一下那篇文章的介紹
不過簡單的說的話,其實就是在 class 上面加上 @RestController
,這樣就可以正確的返回 Json 格式了
基於上述的介紹,我們可以來總結一下,如果想要設計出 RESTful API 的話,需要符合哪三個設計:
只需要同時滿足這三個設計,那就可以將你的 API 稱為 RESTful API 了!恭喜恭喜!
介紹了這麼多 RESTful API 的設計方式,最後來介紹一下使用 RESTful API 的好處,以及在使用 RESTful API 的注意事項
RESTful API 的目的,是為了「簡化工程師之間的溝通成本」,也就是讓每個工程師設計出來的 API 不要差太多,這樣子其他工程師就不用花太多時間來看懂你到底在設計啥,因此大家就可以把溝通所花費的時間省下來,進而提升開發的效率
不過要特別注意的是,雖然 REST 風格的使用非常普遍,有非常多工程師和公司都喜歡採用 REST 風格,但是 REST 只是一個設計 API 的風格而已,並不是設計 API 的標準規範
所以換句話說的話,REST 風格只是一個建議做法,而不是必要的做法,因此大家的使用情境如果比較特殊的話,那麼不遵守 REST 風格的設計也是完全沒問題的!
舉例來說,假設你有一個讀取資料庫的 API,那麼在 REST 風格中就是會設計成使用 GET 方法來請求,但是如果今天你是要用比較敏感的資訊來查詢資料庫,譬如說你要用身分證字號來查詢,那麼在這個情況下,硬要使用 REST 風格的 GET 方法反而是不洽當的(因為請求參數會洩漏出去),這時候反而是使用 POST 這種安全性較高的 Http method,才會是更好的選擇
所以總的來說,REST 只是一個風格,只是用來簡化工程師之間的溝通成本而已,但是實際上還是可以依照工作中的情況來做調整的,重點還是以滿足需求為主!
這篇文章先介紹了什麼是 API,接著介紹了 RESTful API 的概念,以及在設計 RESTful API 時要滿足的三個條件,最後也介紹了使用 RESTful API 的優點以及注意事項,所以大家就可以根據自己的需求,去決定是否要採用 REST 風格來設計你的 API 了!
那麼了解了 RESTful API 的概念之後,下一篇文章,我們就回到 Spring Boot 上來看一下,要如何在 Spring Boot 中實作出 RESTful API 的程式,那我們就下一篇文章見啦!