iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
2
Software Development

30天從零開始 使用 Spring Boot 跟 Spring Cloud 建構完整微服務架構系列 第 4

Day 04 - 增加 Rest Repositories 讓 Spring Data 直接升級為 RestAPI

前一篇只有用到 Spring Data, 但我們很多物件都有 CRUD 的基本操作,
你就必須寫很多 CRUD Controller, CRUD Controller, CRUD Controller, CRUD Controller......

請不要再這樣浪費生命了....
現在起你連一行程式啦都不用寫....

透過 Spring Data 原本提供的功能, 再加上這個套件

compile('org.springframework.boot:spring-boot-starter-data-rest')

然後把原本的 @Repository 換成 @RepositoryRestResource

這樣我們的 Book 物件, 一行程式都不用寫
就可以透過
POST /books
PUT /books/{bookid}
GET /books/{bookid}
DELETE /books/{bookid}

就不用一直重複去寫這些 CRUD 了

但是通常你會有需求不想讓所有 API 對外開放 ex:DELETE /books/{bookid}
你可以進一步用這個註解開控制是否對外 @RestResource(exported = false)

整個改完程式就會像這樣
build.gradle

dependencies {
	compile('org.springframework.boot:spring-boot-starter-data-jpa')
	compile('org.springframework.boot:spring-boot-starter-data-rest')
	compile('org.springframework.boot:spring-boot-starter-web')
	runtime('com.h2database:h2')
	compileOnly('org.projectlombok:lombok')
	testCompile('org.springframework.boot:spring-boot-starter-test')
}

BookRepository.java
我把 CRUD 的 Override 都列出來,
delete 功能我們控制 RestResource(exported = false) 不對外開放

package com.example.book;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.annotation.RestResource;

@RepositoryRestResource
public interface BookRepository extends JpaRepository<Book, Integer> {

    // Prevents GET /books/:id
    @Override
    Book findOne(Integer id);

    // Prevents GET /books
    @Override
    Page<Book> findAll(Pageable pageable);

    // Prevents POST /books and PATCH /books/:id
    @Override
    Book save(Book s);

    // Prevents DELETE /books/:id
    @Override
    @RestResource(exported = false)
    void delete(Book t);
}

程式啟動後可以透過

curl -X GET http://localhost:8080

來知道這服務提供多少個 API 來操作
RestAPI

查詢分頁

curl -X GET 'http://localhost:8080/books?page=0&size=2&sort=bookid,desc'
{
    "_embedded": {
        "books": [
            {
                "name": "天生變態:一個擁有變態大腦的天才科學家",
                "author": "詹姆斯‧法隆",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/books/12"
                    },
                    "book": {
                        "href": "http://localhost:8080/books/12"
                    }
                }
            },
            {
                "name": "魔法精油寶典:102種植物香氣的能量運用",
                "author": "史考特‧康寧罕",
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/books/11"
                    },
                    "book": {
                        "href": "http://localhost:8080/books/11"
                    }
                }
            }
        ]
    },
    "_links": {
        "first": {
            "href": "http://localhost:8080/books?page=0&size=2&sort=bookid,desc"
        },
        "self": {
            "href": "http://localhost:8080/books"
        },
        "next": {
            "href": "http://localhost:8080/books?page=1&size=2&sort=bookid,desc"
        },
        "last": {
            "href": "http://localhost:8080/books?page=5&size=2&sort=bookid,desc"
        },
        "profile": {
            "href": "http://localhost:8080/profile/books"
        }
    },
    "page": {
        "size": 2,
        "totalElements": 12,
        "totalPages": 6,
        "number": 0
    }
}

取得單一資料

curl -X GET http://localhost:8080/books/12
{
    "name": "天生變態:一個擁有變態大腦的天才科學家",
    "author": "詹姆斯‧法隆",
    "_links": {
        "self": {
            "href": "http://localhost:8080/books/12"
        },
        "book": {
            "href": "http://localhost:8080/books/12"
        }
    }
}

然後我們試一下刪除是不是真的會被外面 RestAPI 給刪除

curl -I -X DELETE  http://localhost:8080/books/12
HTTP/1.1 405
Allow: GET,HEAD,PUT,PATCH,OPTIONS
Content-Length: 0
Date: Tue, 12 Dec 2017 01:44:29 GMT

就可以很清楚看到 405 此操作已被拒絕了

你看 CRUD 都不用重複再開發, 查詢也支援分頁

是不是大大節省我們重複寫一些基本操作的時間呢?

work smart not work hard!!

多用一些新的工具節省你的精力, 把時間花在你的商業邏輯吧~~


上一篇
Day 03 - 透過 Spring Data 操作資料庫
下一篇
Day 05 - 增加 Swagger 來提供線上版 API 規格說明
系列文
30天從零開始 使用 Spring Boot 跟 Spring Cloud 建構完整微服務架構35
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
netlabfox
iT邦新手 5 級 ‧ 2021-05-25 17:53:03
    @Override
    Book findOne(Integer id);

查到新版本2.0後有修正成

    @Override
    Optional<Book> findById(Integer id);

用來避免NullPointerException
以上為學習心得,如有錯還請指教

Sam iT邦新手 4 級 ‧ 2021-05-27 10:32:46 檢舉

/images/emoticon/emoticon12.gif

我要留言

立即登入留言