[Day 19] 遠征 Kotlin × Spring Boot 使用 RESTful API (2)

在前一篇 Spring Boot 使用 RESTful API (1) 我們已經說明 RESTful API 的基本概念,接下來這篇我們要將前面所做的範例進行修改,實作步驟如下:

運用的範例是在 第16篇「使用 Spring Data JPA 操作資料庫 (1)」 的 Github 範例,有興趣的朋友也可以直接下載範例練習實作
從此篇開始,我們預計會在實作上加入 Kotlin 特性的撰寫風格,例如 Kotlin 章節所提到的 Scope Function、Elvis等特性

  1. 我們在之前的範例,其實已經完成 GetPost 等 API 操作,使用資源名稱為 students,如下範例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    @RestController
    @RequestMapping("/api")
    class StudentController(@Autowired val studentDao: StudentDao) {
    /**
    * 取得 Student 所有資料
    */
    @GetMapping("/students")
    fun getStudentData(): MutableList<Student> = studentDao.findAll()

    /**
    * 新增 Student 資料
    */
    @PostMapping("/students")
    fun addStudentData(@RequestBody student: Student): Student = studentDao.save(student)

    /**
    * 利用姓名查詢學生資料
    */
    @PostMapping("/students/search")
    fun getStudentByName(@RequestParam name: String): ResponseEntity<List<Student>>
    = studentDao
    .findByName(name)
    .let {
    return ResponseEntity(it, HttpStatus.OK)
    }
    }
  2. 新增 PUT 實作 - 更新學生資料

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /**
    * 修改學生全部資料
    */
    @PutMapping("/students/{id}")
    fun updateStudent(@PathVariable id: Int, @RequestBody student: Student): ResponseEntity<Student?>
    = studentDao
    .findById(id)
    .run {
    this ?: return ResponseEntity<Student?>(null, HttpStatus.NOT_FOUND)
    }.run {
    return ResponseEntity<Student?>(studentDao.save(this), HttpStatus.OK)
    }
  3. 新增 PATCH 實作 - 修改部份學生資料,此步驟要記得 PUTPATCH 的差異,根據 RESTful 定義,通常會使用 PATCH 的呼叫會屬於僅修改部份資料的 API,此範例以修改學生信箱 API 為例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    /**
    * 修改學生信箱(欲更新部份資料)
    */
    @PatchMapping("/students/{id}")
    fun updateStudentEmail(@PathVariable id: Int, @RequestBody email: String): ResponseEntity<Student?>
    = studentDao
    .findById(id)
    .run {
    this ?: return ResponseEntity<Student?>(null, HttpStatus.NOT_FOUND)
    }
    .run {
    Student(
    id = this.id,
    name = this.name,
    email = email
    )
    }
    .run {
    return ResponseEntity<Student?>(studentDao.save(this), HttpStatus.OK)
    }
  4. 新增 DELETE 實作 - 刪除學生資料

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /**
    * 刪除學生資料
    */
    @DeleteMapping("/students/{id}")
    fun deleteStudent(@PathVariable id: Int): ResponseEntity<Any>
    = studentDao
    .findById(id)
    .run {
    this ?: return ResponseEntity<Any>(null, HttpStatus.NOT_FOUND)
    }
    .run {
    return ResponseEntity<Any>(studentDao.delete(this), HttpStatus.NO_CONTENT)
    }
  5. 修改測試檔案 Student.http - 增加 PUTPATCHDELETE 測試方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    ### 取得所有學生資料 API
    GET http://localhost:8080/api/students

    ### 新增學生資料 API
    POST http://localhost:8080/api/students
    Content-Type: application/json

    {
    "name": "Devin",
    "email": "test@gmail.com"
    }

    ### 利用姓名參數查詢學生資料
    POST http://localhost:8080/api/students/search?name=Devin
    Content-Type: application/json

    ### 修改學生資料
    PUT http://localhost:8080/api/students/1
    Content-Type: application/json

    {
    "name": "Eric",
    "email": "Eric@gmail.com"
    }

    ### 修改學生信箱資料
    PATCH http://localhost:8080/api/students/1
    Content-Type: application/json

    {
    "email": "test@gmail.com"
    }

    ### 刪除學生資料
    DELETE http://localhost:8080/api/students/1

以上,是我們根據 RESTful API 設計風格進行實作,最後這邊還是想提醒閱讀的朋友,雖然 RESTful是一個非常流行的API設計風格,大多公司都會使用到,但實際在開發專案時,還是會根據專案需求、團隊規範或是公司文化而會有所不同,畢竟設計風格只是一種參考,千萬不要變成開發的阻礙,架構應該要因應每種需求而有不同的改變,進而找出最適合的方式。

此文章有提供範例程式碼在 Github 供大家參考