簡介
Spring Data REST是Spring Data項目的一部分,可輕松在Spring Data存儲庫上構建超媒體驅動的REST Web服務。
Spring Data REST 構建在 Spring 數據存儲庫之上,分析應用程序的域模型,並公開模型中包含的聚合的超媒體驅動的 HTTP 資源。
特征:
- 使用 HAL 媒體類型來公開域模型的 REST API。
- 適用集合、項目(item)和關聯資源表示你的模型。
- 通過鏈接導航支持分頁。
- 允許動態過濾收集資源。
- 通過資源api來暴露你repositories中定義的資源查詢方法。
- 允許通過處理Spring ApplicationEvents來處理REST請求。
- 公開有關ALPS和JSON Schema模型的元數據。
- 允許通過投影定義客戶特定的表示形式。
- 發布一個定制的HAL瀏覽器變體以利用公開的元數據。
- 目前支持JPA,MongoDB,Neo4j,Solr,Cassandra,Gemfire。
- 允許對公開的默認資源進行高級自定義。
💡:目前對Spring Data REST適用分析:快速生成數據庫資源對外的接口(適用於一些邏輯簡單的數據對外接口)
分析
使用Spring Data REST並實現以下功能來滿足日常api的開發過程:
需要滿足的一些要求: 1.針對字段級別,方法級別,類級別進行限制(禁止某些字段,方法,接口的對外映射)。 2.對數據增刪改查的限制(禁止某些請求方法的訪問)。 3.能個性化定義請求的路徑。 4.對所傳參數進行值校驗。 5.響應統一處理。 6.異常處理。 7.數據處理的切面。
以上列出了我們日常接口開發中比較常見的一些功能需求,這里將演示使用Spring Data REST並結合實現上述功能來快速開發HAL REST API。
准備
條件:
jdk11
Springboot 2.2.6.RELEASE
maven
Spring Data JPA
添加依賴
本文中演示Spring Data JPA結合Spring Data REST
1.添加Spring Data持久層依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
目前Spring Data REST支持JPA,MongoDB,Neo4j,Solr,Cassandra,Gemfire,所以使用時可根據自己的需求引入不同的Spring Data依賴,本文將使用JPA作為演示。
2.添加Spring Data REST相關依賴
<!--Spring Data REST-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<!--Spring Data REST 數據瀏覽工具-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
簡單嘗試
示例中將用一個簡單的租客系統來做演示。
創建一個房子類
@Entity
@Data
@Accessors(chain = true)
public class House {
@Id
@GeneratedValue
private Long id;
private String houseNumber;
private String owner;
private String idCard;
public House() {
}
public House(String houseNumber, String owner, String idCard) {
this.houseNumber = houseNumber;
this.owner = owner;
this.idCard = idCard;
}
}
創建一個租客類
@Entity
@Data
@Accessors(chain = true)
public class Tenant {
@Id
@GeneratedValue
private Long id;
private String name;
//隱私信息不需要暴露
private String idCard;
private String mobile;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime rentDateTime;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
private House house;
public Tenant() {
}
public Tenant(String name, String idCard, String mobile, LocalDateTime rentDateTime, House hous) {
this.name = name;
this.idCard = idCard;
this.mobile = mobile;
this.rentDateTime = rentDateTime;
this.house = hous;
}
}
此時,我們新建一個租客的Reopsitory
public interface TenantRepository extends CrudRepository<Tenant, Long> {
Page<Tenant> findAllByNameContaining(String name, Pageable page);
Page<Tenant> findAllByIdCardContaining(String idCard, Pageable page);
Tenant findFirstByMobile(String mobile);
Tenant findFirstByIdCard(String idCard);
}
運行前我們准備好初始化數據
@SpringBootApplication
public class SpringDataRestDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDataRestDemoApplication.class, args);
}
@Resource
private TenantRepository tenantRepository;
@PostConstruct
public void initRepo() {
//准備房子信息
List<House> houses = new ArrayList<>();
House zhangsan = new House("1101", "張三", "330521******1");
House zhangsi = new House("1102", "張四", "330521******2");
House zhangwu = new House("1103", "張五", "330521******3");
House zhangliu = new House("1104", "張六", "330521******4");
House zhangqi = new House("1105", "張七", "330521******5");
House zhangba = new House("1106", "張八", "330521******6");
//准備租客信息
List<Tenant> tenants = new ArrayList<>();
tenants.add(new Tenant("王一", "330522******1", "186****3331", LocalDateTime.now().minusDays(1), zhangsan));
tenants.add(new Tenant("王二", "330522******2", "186****3332", LocalDateTime.now().minusDays(2), zhangsi));
tenants.add(new Tenant("王三", "330522******3", "186****3333", LocalDateTime.now().minusDays(3), zhangwu));
tenants.add(new Tenant("王四", "330522******4", "186****3334", LocalDateTime.now().minusDays(4), zhangliu));
tenants.add(new Tenant("王五", "330522******5", "186****3335", LocalDateTime.now().minusDays(5), zhangqi));
tenants.add(new Tenant("王六", "330522******6", "186****3336", LocalDateTime.now().minusDays(6), zhangba));
tenantRepository.saveAll(tenants);
}
}
啟動項目,並且訪問localhost:8080,如下圖:
上圖是Spring Data REST的HAL數據瀏覽器,通過它能高效的查詢和調試Spring Data REST對外提供的接口。
我們可以看到響應內容的格式,正是符合HAL類型的格式。
訪問http://localhost:8080/tenants/search
上圖可以看到,Spring Data REST對外暴露了我們在Repository中定義的查詢方法,並且可以看到response Body中數據格式符合HAL格式類型,通過HAL格式的響應數據,我們輕松就能知道這些查詢方法對應的請求路徑,起到了一個文檔的作用,使api能夠自發現。
總結
本文初步的介紹了Spring Data REST的功能及特征,並且演示了如何在項目中引入Spring Data REST,並結合Spring Data REST實現了簡單的演示Demo。下一篇文章將介紹並演示如何在Spring Data REST中實現一些必要的功能,以此來滿足我們日常的接口開發工作。
本文代碼示例:https://gitee.com/jeker8chen/spring-data-rest-in-practice.git
關注筆者公眾號,推送各類原創/優質技術文章 ⬇️