iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
Software Development

Spring Boot 零基礎入門系列 第 22

Spring Boot 零基礎入門 (22) - 實作 RESTful API - @GetMapping、@PostMapping...

  • 分享至 

  • xImage
  •  

賀!此系列文榮獲 2023 iThome 鐵人賽《優選》獎項,正在規劃出書中,感謝大家的支持🙏,同名課程「Java 工程師必備!Spring Boot 零基礎入門」也已在 Hahow 平台上架

哈囉大家好,我是古古

在上一篇文章中,我們有介紹了什麼是 RESTful API,以及要設計出 RESTful API,需要滿足哪三個設計條件

那麼接著這篇文章,我們就實際的到 Spring Boot 上,來看一下要如何在 Spring Boot 中設計和實作出 RESTful API!

回顧:什麼是 RESTful API?


RESTful API 是指「你所設計的 API 符合 REST 風格」,而 RESTful API 的目的,就是在「簡化工程師之間的溝通成本」,讓大家可以設計出更一致的 API,就不用老是在問彼此這邊設計的到底是什麼意思

而要設計出 RESTful API 的話,需要符合以下三個設計:

  1. 使用 Http method 來表示動作
  2. 使用 url 路徑描述資源之間的階層關係
  3. response body 返回 json 或是 xml 格式

只需要同時滿足這三個設計,就可以將你的 API 稱呼為是 RESTful API 了!

https://ithelp.ithome.com.tw/upload/images/20231007/20151036Ck7GNzju0H.png

在 Spring Boot 中設計和實作 RESTful API


了解了 RESTful API 的概念之後,接著這篇文章,就會實際的到 Spring Boot 中,嘗試在 Spring Boot 程式裡面設計出一套出 RESTful API 出來

舉例來說,我們可以先設計出一個 Student 的 class,並且在裡面新增 id 和 name 的兩個變數,表示這個學生的 id 和名字

public class Student {
    Integer id;
    String name;
}

接著,我們可以為 Student 這個資源,去設計出一連串的 RESTful API

  • 譬如說我們需要一個「創建學生」的 API ,這樣子才能新增新生的數據到資料庫
  • 或是我們也需要一個「查詢學生」的 API,這樣子才能去查詢某一筆 Student 的數據出來
  • ...等等

而這樣子的一個「資源」(此處就是指 Student),通常我們會設計 4 個最基本的 RESTful API 給他,如下圖所示:

https://ithelp.ithome.com.tw/upload/images/20231007/20151036cNvBle2WDL.png

所以透過上面這張圖也可以看到,針對一個 Student 這個資源,我們就可以設計這 4 個 RESTful API 給他,完成他最基本的「新增、查詢、修改、刪除」的四個操作了!

補充:「新增、查詢、修改、刪除」這四個操作,又可以被簡稱為 CRUD,幾乎每一種資源(ex: 商品、訂單、會員...等),都會需要這四個操作,因此 CRUD 也可以說是大家初入門 Spring Boot 最常撰寫的程式

指定 Http method 的方式:@GetMapping、@PostMapping...


在上面那張表格圖可以看到,對於一個資源,我們通常會設計這 4 個 RESTful API 出來,所以到時候,假設前端想要去查詢 Student 的數據時,就只能夠使用 GET 方法,去請求 /students/123 的 url 路徑,如果前端不小心誤用其他的請求方法(像是 DELETE)去請求 /students/123 的 url 路徑的話,那是沒辦法正確查詢出 Student 的數據的

不過,到目前為止,我們還沒有介紹要如何在 Spring Boot 中,去指定前端只能用某個特定的 Http method 來請求,因此我們可以先回頭來介紹這部分,再接著往下實作 Spring Boot 程式

在 Spring Boot 中,有兩種方式可以「限制」前端只能用某個 Http method 來請求 url 路徑,分別是:

1. @RequestMapping(value = "/students", method = RequestMethod.POST)
2. @PostMapping("/students")

上面這兩種寫法,都可以限制前端只能使用 POST 方法,來請求這個 /students 的 url 路徑,而他們的差別,就只是一行寫起來比較長、一行寫起來比較短而已

在這篇文章之前,我們都是使用第一種的 @RequestMapping 的寫法來設計 url 路徑的,不過他的缺點,就是寫起來比較冗長,不利於後續維護

所以通常在實務上,是會改成使用第二種的 @PostMapping,直接在註解裡面,就去限制前端只能使用 POST 方法來請求,這樣子的寫法更簡潔、更一目瞭然,所以在設計 RESTful API 時,通常就是會採用第二種 @PostMapping 的方式來使用

補充:如果沒有在 @RequestMapping 後面的小括號中,特別添加 method = RequestMethod.POST 的設定的話,那就是所有的 Http method 都接受,沒有特別限制

RESTful API 系列註解

而在 Spring Boot 裡面,除了可以使用 @PostMapping 來限制前端只能使用 POST 方法來請求之外,也是有其他的註解可以用來限制其他的 Http method 的

  • 譬如說 @GetMapping,就可以用來限制只能使用 GET 方法請求
  • 或是 @PutMapping,就限制只能使用 PUT 方法來請求

不過這些註解大家不需要死記,只要觀察一下就可以發現,其實這些 @PostMapping@GetMapping....等等,他們都是「以 Http method 作為開頭的註解」,然後在後面加個 Mapping 而已

所以假設你今天想要限制只能用 GET 請求,那就是直接打 @Get..,接著 Spring Boot 就會提示你可以拿 @GetMapping 來使用,如果你今天想要限制只能用 DELETE 請求,那就一樣是直接打 @Delete...,Spring Boot 一樣是會提示可以拿 @DeleteMapping 來使用

所以簡單的說的話,就是在 RESTful API 的實作上,Spring Boot 也提供了許多方便好用的註解,讓我們可以更快速的去限制,這個 API 只能使用哪些方法來請求

補充:常用的 RESTful API 註解

最常用的 RESTful API 註解就是

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping

因此大家若是剛接觸不太熟悉,也可以先把這四個背起來就好

前期準備


了解了 Spring Boot 對 RESTful API 的支援,並且也設計好我們接下來要實作的 4 個 RESTful API 之後,接下來我們就可以實際的到 Spring Boot 中,來實作這 4 個 RESTful API 出來了!

大家可以先在 Spring Boot 程式中,創建一個新的 class,名字叫做 Student,並且在裡面寫上如下的程式:

public class Student {

    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

並且再創建出一個新的 class,名字叫做 StudentController,並且在裡面寫上如下的程式:

@RestController
public class StudentController {
    
    
}

所以整個 Spring Boot 結構會如下所示

https://ithelp.ithome.com.tw/upload/images/20231007/20151036ZOKpRi810G.png

1. 實作 POST /students


首先 POST /students 這個方法所代表的意義,即是「創建一個 Student 出來」

https://ithelp.ithome.com.tw/upload/images/20231007/20151036McGCDPtKcQ.png

而要實作 POST /students 方法的話,可以先運用上面介紹的 RESTful API 相關註解,使用 @PostMapping 去指定此方法只能夠使用 POST 方法來請求

而參數部分,基本上就是照著 Day 19 - 取得請求參數 (上) - @RequestParam、@RequestBody 文章中的 @RequestBody 的介紹,在 create() 方法中新增一個 Student 類型的參數,並且在最前面加上 @RequestBody

這樣到時候 Spring Boot 就會將前端放在 request body 中的 Json 格式,給轉換成是這個 student 類型的參數,並且把 Json 中的值儲存在 student 參數裡面了

實際程式

@PostMapping("/students")
public String create(@RequestBody Student student) {
    return "執行資料庫的 Create 操作";
}

API Tester 中的請求寫法

https://ithelp.ithome.com.tw/upload/images/20231007/20151036uMDKsWbcpf.png

2. 實作 GET /students/123


GET /students/123 這個方法所代表的意義,是去「查詢 student id 為 123 的資訊」出來

https://ithelp.ithome.com.tw/upload/images/20231007/20151036M36Wyix6vU.png

要實作 GET /students/123 方法的話,一樣是可以先運用上面提到的 RESTful API 註解,使用 @GetMapping 去指定此方法只能夠使用 GET 方法來請求

另外在這裡,因為 RESTful API 會使用「url 路徑來表達階層關係」,所以我們想要取得到的 student id 的值,就會被放在 url 路徑 /students/123 裡面

因此這時候我們就得派上 @PathVariable ,幫助我們從 /students/123 這個 url 路徑中,取得到其中的 123 的數據

有關 @PathVariable 的用法,可以參考 Day 20 - 取得請求參數 (下) - @RequestHeader、@PathVariable 文章中的介紹

實際程式

@GetMapping("/students/{studentId}")
public String read(@PathVariable Integer studentId) {
    return "執行資料庫的 Read 操作";
}

API Tester 中的請求寫法

https://ithelp.ithome.com.tw/upload/images/20231007/20151036ANolVhH9Nv.png

3. 實作 PUT /students/123


PUT /students/123 這個方法所代表的意義,是去「更新 student id 為 123 的資訊」

https://ithelp.ithome.com.tw/upload/images/20231007/20151036FFVfvashYd.png

更新的方法算是實作上比較複雜的一個方法,不過首先一樣是先運用上面提到的 RESTful API 註解,使用 @PutMapping 去指定此方法只能夠使用 PUT 方法來請求

而在參數的部分,這裡會同時用到 @PathVariable@RequestBody 這兩個註解

  • @PathVariable 負責將「要更新的是哪一個 student id」的值,從 url 路徑中取得出來(也就是 /students/123 中的 123 啦)
  • @RequestBody 則是負責去接住前端傳過來的 Json 格式,了解前端想要把這個 Student 的值改成什麼樣子

有關 @PathVariable@RequestBody 的用法,一樣是可以參考前面文章的介紹,也建議可以先完成前面的 POST 和 GET 實作之後,再來練習 PUT 實作會好一點

實際程式

@PutMapping("/students/{studentId}")
public String update(@PathVariable Integer studentId,
                     @RequestBody Student student) {
    return "執行資料庫的 Update 操作";
}

API Tester 中的請求寫法

https://ithelp.ithome.com.tw/upload/images/20231007/20151036zwMLAmjE3u.png

4. 實作 DELETE /students/123


DELETE /students/123 這個方法所代表的意義,是去「刪除 student id 為 123 的資訊」出來

https://ithelp.ithome.com.tw/upload/images/20231007/20151036N6KJmojovR.png

DELETEGET 的實作方式其實滿像的,要實作 DELETE /students/123 方法的話,一樣是可以先運用上面提到的 RESTful API 註解,使用 @DeleteMapping 去指定此方法只能夠使用 DELETE 方法來請求

另外也因為 RESTful API 會使用「url 路徑來表達階層關係」,所以需要使用 @PathVariable,從 url 路徑 /students/123 裡面取得到 123 的 student id 的數據

實際程式

@DeleteMapping("/students/{studentId}")
public String delete(@PathVariable Integer studentId) {
    return "執行資料庫的 Delete 操作";
}

API Tester 中的請求寫法

https://ithelp.ithome.com.tw/upload/images/20231007/201510360TiEPYtrGi.png

小結:在 Spring Boot 中實作 RESTful API


所以透過上面的 4 個 RESTful API 的實作,最後在這個 StudentController 裡面的程式就會長得像是下圖的樣子

https://ithelp.ithome.com.tw/upload/images/20231007/20151036S3K4PybrnJ.png

因此後續我們就可以根據這 4 個 RESTful API,去對 Student 這個資源,進行「新增、查詢、修改、刪除」這四個 CRUD 的基本操作了!

總結


這篇文章介紹了要如何在 Spring Boot 中去設計和實作 RESTful API,並且也介紹了 Spring Boot 為 RESTful API,所提供的一系列好用的 @GetMapping@PostMapping....註解,因此大家如果也想要開發 RESTful API 的話,就可以借助這些工具的力量,快速實作完很 RESTful 的 API 了

那麼下一篇文章,我們會來介紹一下在 Http response 中也是很重要的一個部分,即是 Http status code,透過 Http status code,前端就可以快速知道目前的請求結果到底是成功或是失敗的,那我們就下一篇文章見啦!

相關連結



上一篇
Spring Boot 零基礎入門 (21) - RESTful API 介紹
下一篇
Spring Boot 零基礎入門 (23) - Http status code(Http 狀態碼)介紹
系列文
Spring Boot 零基礎入門30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
trytrycan13
iT邦新手 5 級 ‧ 2023-10-07 21:01:58

補充:如果沒有在 @ReqeustMapping 後面的小括號中,特別添加 method = RequestMethod.POST 的設定的話,那就是所有的 Http method 都接受,沒有特別限制

這邊的 @RequestMapping,有拼寫筆誤

古古 iT邦新手 4 級 ‧ 2023-10-07 21:07:41 檢舉

感謝提醒!已修正

也謝謝老師每日更新文章,受益良多!

我要留言

立即登入留言