目錄

Day 21 - RESTful API 介紹

古古

2024/07/21


哈囉大家好,我是古古。

在前幾篇文章中,我們分別介紹了 Spring Boot 中「取得前端參數」的四個註解,因此大家就可以根據不同的情境,使用不同的註解來取得前端傳遞過來的參數了。

那麼這篇文章,我們就會介紹現今前後端開發非常流行的一種設計風格,也就是 RESTful API,所以我們就開始吧!

什麼是 API? #

在開始介紹「RESTful API」之前,大家需要先了解「API」是什麼,要先掌握 API 的概念,才能夠學習 RESTful API 的相關知識,因此我們就先來介紹一下,API 到底是什麼。

所謂的 API,指的是「用工程師的方式,去說明某個功能的使用方法」,所以換句話說的話,API 就是用特定的格式,去表示某個功能到底要怎麼使用,等於是一個使用說明書的概念。

舉例來說,假設我們在 Spring Boot 中實作了一個「取得商品列表」的功能,那麼當我們想要將這個功能開放給前端使用的話,總不可能直接把 Spring Boot 的程式貼給對方看(因為對方可能不熟悉 Spring Boot、或是他根本不了解 Java 程式語言),因此就會造成溝通效率低落。

而為了解決這個問題,API 就出現了!

因為 API 的目的,就是「用工程師看得懂的方式,去說明某個方法要如何使用」,所以我們就可以用下圖中的格式,去定義「取得商品列表」這個 API 的使用方法。

像是在下圖中,就會說明「取得商品列表」這個 API,必須要使用 GET 來請求。並且這張圖也有詳細列出前端在請求時,可以帶上什麼樣的請求參數(query parameter),以及這個 API 可能返回的 Http response 為何。

所以當前端拿到這份 API 文件時,前端就能夠照著上面的定義,去使用 GET 請求 /getProducts 這個 url 路徑,並且在請求時,帶上 size=5 這個請求參數(表示要取得 5 筆數據),這樣子就可以成功的去使用「取得商品列表」的功能,進而去取得 5 筆商品數據出來了!

因此透過這份 API 文件,大家就可以更清楚的知道某個功能的使用方式,進而提升前後端溝通的效率!

補充:一般在口語上,大家可能會聽到有人說「這支 API 要怎麼 call?」或是「你可以去 call 商品功能的 API」這種說法,其中的「call API」,其實就是指「對該 API 發起 Http 請求」的意思。

所以假設我們在 Spring Boot 中實作了一個 API,他的 url 路徑是 /test,那麼當前端去請求 http://localhost:8080/test 時,就可以說「前端去 call 了 /test 這一支 API」。

因此「call API」這個說法,在實務上是非常常見的講法,所以建議大家也要熟悉一下這個講法會比較好!

什麼是 RESTful API? #

了解了 API 的概念之後,接著就可以來介紹什麼是「RESTful API」了!

所謂的「RESTful API」,就是表示去設計出一套「符合 REST 風格的 API」出來,所以換句話說的話,只要我們在設計 API 時,有去套用 REST 風格,那就可以稱呼我們所設計出來的這組 API,是 RESTful API 了!

補充:大家看到這邊,可能會疑惑「REST 風格」和「RESTful」之間到底是什麼關係,其實這裡只是用到英文的文法特性而已。

在英文的文法裡面,有一種用法,就是在字尾加個 ful,就可以把名詞轉成形容詞。

舉例來說:

  • Beauty 是名詞(意思是美麗),而 Beautiful 則是形容詞(美麗的)
  • Peace 是名詞(意思是和平),而 Peaceful 則是形容詞(和平的)

因此同樣的邏輯,REST 是一個名詞,表示「REST 風格」,而 RESTful 就是形容詞,表示「符合 REST 風格的」,所以 RESTful API 的意思,就是表示「這個 API 是很符合 REST 風格的」!

大概了解 REST 和 RESTful 的差別之後,所以現在我們知道,所謂的「RESTful API」,就是設計出一個「符合 REST 風格的 API」,而如果我們想要設計出一個「符合 REST 風格的 API」,那麼這個 API 就必須要滿足三個條件:

1. 成為 RESTful API 的條件之一:使用 Http method,表示要執行的資料庫操作 #

如果想要設計出 RESTful API 的話,首先第一點,就是這個 API 必須要「使用 Http method,去表示要執行的資料庫操作」,也就是賦予了 Http method 更多的意義。

在 REST 風格中,REST 風格會把 POST、GET、PUT、DELETE 這四種 Http method,分別去對應到資料庫的 Create、Read、Update、Delete 操作上。

所以在 REST 風格中,只要看到某支 API 是使用 GET 來請求,那就是在暗示這個 API 會去資料庫中執行「Read(查詢數據)」的操作。或是如果該 API 是使用 POST 來請求,那就是在暗示這個 API 要去執行「Create(新增數據)」的操作。

因此在 RESTful API 的世界裡面,Http method 影響的不僅僅是 GET、POST 這些請求參數的傳遞而已,也是在「暗示」這支 API 後續會去執行資料庫中的哪種操作。

所以如果我們想要設計出一個 RESTful API 的話,那麼第一個必要條件,就是要「使用 Http method,去表示要執行的資料庫操作」。

2. 成為 RESTful API 的條件之二:使用 url 路徑,描述資源之間的階層關係 #

成為 RESTful API 的第二個條件,就是「使用 url 路徑,描述資源之間的階層關係」。

在 REST 風格裡面,url 路徑代表的是「每個資源之間的階層關係」,這個聽起來可能有點抽象,所以我們可以直接透過一個例子,來了解什麼是資源之間的階層關係。

假設現在有一個使用 GET 來請求 API 為 GET /users,首先因為這個 API 是使用 GET 來請求,因此根據上面的條件一的介紹,GET 就是對應到 Read(讀取數據)的操作,又因為後面的 url 路徑是 /users,所以我們就可以知道他是要去「取得所有 user 的數據」。

此時假設我們又有另一個 API GET /users/123,因為這個 API 也是使用 GET 來請求,所以也是去讀取數據,並且他的 url 路徑是 /users/123,因此這個 API 的含義,就是「取得 user id 為 123 的那個 user 的數據」。

而到這邊,REST 風格的階層概念其實就出現了!

大家可以把 url 路徑中的每一個斜線 /,想像成是一個個的階層,也就是一個子集合的感覺。或是說得更白話一點,就是可以直接把這個斜線 /,替換成是中文的「的」。

  • 所以像是上面的 GET /users,就是表示去「取得所有 user 的數據」
  • 而下面的 GET /users/123,則是表示去取得所有 user 中「的」user id 為 123 的數據,所以就是「取得 user id 為 123 的那個 user 的數據」

因此在 REST 風格裡面,我們就要透過 url 路徑,去表達「階層」的概念,並且透過 url 路徑,就可以去表達我們想要取得的資源是什麼了!

下面也提供更多例子給大家參考,讓大家感受一下在 REST 風格中,url 路徑所表示的階層關係:

所以如果我們想要設計出一個 RESTful API 的話,第二個必要條件,就是要「使用 url 路徑,描述資源之間的階層關係」。

3. 成為 RESTful API 的條件之三:Response body 返回 JSON 或是 XML 格式 #

而至於成為 RESTful API 的最後一個條件,這個就比較簡單了,只要確保「Response body 所返回的數據,是使用 JSON 或是 XML 格式來返回」,這樣子就滿足 RESTful API 的第三個條件了!

補充:雖然一般在實作上,比較常使用 JSON 格式來返回數據,但是其實使用 XML 格式來回傳數據,也是符合 REST 風格的!

而在 Spring Boot 中,如果要返回 JSON 格式的數據的話,就只要在 class 上面加上 @RestController,並且將返回的類型改成「Java 物件」,這樣子就可以回傳 JSON 格式的數據給前端了。

如果對 Spring Boot 返回 JSON 數據的寫法不太熟悉的話,也可以回頭參考 Day 17 - 返回值改成 JSON 格式 - @RestController 那篇文章的介紹。

小結:滿足 RESTful API 的三個條件 #

所以總和上述的介紹,如果我們想要設計出一個 RESTful API 的話,那麼就需要符合以下三個條件:

  1. 使用 Http method,去表示要執行的資料庫操作
  2. 使用 url 路徑,描述資源之間的階層關係
  3. Response body 返回 JSON 或是 XML 格式

只需要同時滿足這三個條件,那麼你的 API 就是一個「符合 REST 設計風格的 API」,所以也就可以稱呼他為 RESTful API 了!讚!!

補充:RESTful API 的注意事項 #

介紹了這麼多 RESTful API 的設計方式,最後我們也來補充一下,在使用 RESTful API 的一些注意事項。

RESTful API 的目的,是為了「簡化工程師之間的溝通成本」而設計出來的,所以 RESTful API 就是希望可以讓每個工程師能夠按照一個共同的默契來設計 API,這樣每位工程師所設計出來的 API 就不會相差太多,因此大家就可以節省溝通的時間,進而提升開發的效率。

不過要特別注意的是,雖然 REST 風格的使用非常普遍,但是 REST 只是一個設計 API 的風格而已,並不是設計 API 的標準規範。

所以換句話說的話,REST 風格只是一個建議做法,而不是必要的做法,因此如果你的使用情境比較特殊的話,那麼不遵守 REST 風格的設計,也是完全沒問題的!

舉例來說,假設你有一個讀取資料庫的 API,因為讀取是對應到 GET 請求,所以在 REST 風格中就會設計成 GET 請求,也就是類似於 GET /users/{userId} 這種寫法。

但是如果你的系統是要用比較敏感的資訊來查詢資料庫(ex: 身分證字號),那麼在這種情況下,硬要使用 REST 風格的 GET 請求反而是不恰當的,因為這樣身分證字號的資訊就會被放在 url 路徑中來傳遞 GET /users/B123456789,進而導致身分證字號洩漏出去。因此在這種情況下,反而是改用 POST 這種安全性較高的 Http method,才會是更好的 API 設計。

所以總結來說,REST 只是一個設計的風格而已,並不是設計 API 的標準規範,所以如果在實務上真的遇到一些特殊情況時,那就仍舊是以當下的實際情況來做調整,並不是符合 REST 風格的 API 才是最好的。因此大家在實作上,要特別注意這個細節,切勿為了滿足 REST 設計風格,而使得你的 API 暴露在資安風險底下!

總結 #

這篇文章我們先介紹了 API 和 RESTful API 的概念,也介紹了在設計 RESTful API 時要滿足的三個條件,並且最後也補充了使用 RESTful API 注意事項,因此大家就可以根據自己的需求,去決定是否要採用 REST 風格來設計你的 API 了!

那麼在了解了 RESTful API 的概念之後,下一篇文章我們就會回到 Spring Boot 上,來練習要如何在 Spring Boot 中實作出 RESTful API 的程式,那我們就下一篇文章見啦!

補充:本文是擷取自我開設的線上課程 Java 工程師必備!Spring Boot 零基礎入門 的內容,如果你想了解更多的 Spring Boot 的用法,歡迎參考課程簡介 (輸入折扣碼「HH202504KU」即可享 85 折優惠)。