简化RESTful开发,Spring Data REST让你少掉发
1 前言
Springboot + Spring MVC
大大简化了 Web
应用的 RESTful
开发,而 Spring Data REST
更简单。 Spring Data REST
是建立在 Data Repository
之上的,它能直接把 resository
以 HATEOAS
风格暴露成 Web
服务,而不需要再手写 Controller
层。
HATEOAS
,即 Hypermedia as the Engine of Application State ,它是一种更成熟的 REST
模型,在资源的表达中包含了链接信息,客户端可以根据链接来发现可执行的动作。
Spring Data REST
支持 Spring Data JPA
、 Spring Data MongoDB
、 Spring Data Neo4j
、 Spring Data GenFire
、 Spring Data Cassandra
,这里选择大家比较熟悉的 JPA
。
2 举个例子
我们用例子来感受一下吧。
2.1 创建项目
我们通过 Spring Initializr 来快速创建 Springboot
项目。选中的依赖组件如下:
- (1)
Spring Web
:提供Web
服务; - (2)
Rest Repositories
:提供Spring Data REST
的支持; - (3)
Spring Data JPA
:通过JPA
提供Repository
方式的数据访问; - (4)
H2 Database
:H2
数据库,为了方便简洁,使用该数据库。
导入后对应的 pom.xml
中依赖如下:
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-data-rest com.h2database h2 runtime
2.2 实体类
创建一个实体类 User
,如下所示:
package com.pkslow.rest.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String name; private Integer age; private String email; //getter & setter }
2.3 Repository接口定义
定义 Repository
接口用于操作数据库,如下所示:
package com.pkslow.rest.repo; import com.pkslow.rest.entity.User; import org.springframework.data.repository.CrudRepository; import org.springframework.data.rest.core.annotation.RepositoryRestResource; @RepositoryRestResource(path = "user") public interface UserRepository extends CrudRepository { }
注解 RepositoryRestResource
是 Data REST
用于暴露 Repository
, path
为访问路径,设置为 user
,则访问地址为 http://localhost:8080/user
。
2.4 启动访问
准备好以上代码,直接启动 Springboot
应用即可,我们把端口设置为 8080
,访问如下:
我们用 Postman
做一个基本操作。
新增:
查询:
通过主键 ID
查询:
修改:
删除:
不难发现,返回的 Json
都带有链接,这就是 HATEOAS
风格。
3 更多探索
3.1 分页及排序功能
可以快速实现分页及排序功能,只需要把 Repository
的父接口改为 PagingAndSortingRepository
即可,如下所示:
@RepositoryRestResource(path = "user") public interface UserRepository extends PagingAndSortingRepository { }
其实就是多了两个方法 findAll(Sort var1)
和 findAll(Pageable var1)
,如下所示:
public interface PagingAndSortingRepository extends CrudRepository { Iterable findAll(Sort var1); Page findAll(Pageable var1); }
查询 http://localhost:8080/user?page=1&size=2&sort=id,desc
,表示查询第二页,每页2条记录,以 ID
倒序展示。如下:
{ "_embedded": { "users": [ { "name": "pkslow.com", "age": 18, "email": "pkslow@pkslow.com", "_links": { "self": { "href": "http://localhost:8080/user/33" }, "user": { "href": "http://localhost:8080/user/33" } } }, { "name": "pkslow.com", "age": 18, "email": "pkslow@pkslow.com", "_links": { "self": { "href": "http://localhost:8080/user/32" }, "user": { "href": "http://localhost:8080/user/32" } } } ] }, "_links": { "first": { "href": "http://localhost:8080/user?page=0&size=2&sort=id,desc" }, "prev": { "href": "http://localhost:8080/user?page=0&size=2&sort=id,desc" }, "self": { "href": "http://localhost:8080/user?page=1&size=2&sort=id,desc" }, "next": { "href": "http://localhost:8080/user?page=2&size=2&sort=id,desc" }, "last": { "href": "http://localhost:8080/user?page=17&size=2&sort=id,desc" }, "profile": { "href": "http://localhost:8080/profile/user" } }, "page": { "size": 2, "totalElements": 35, "totalPages": 18, "number": 1 } }
可以发现 page
是从 0
开始的, 1
表示第二页;返回结果还提供了第一页、上一页、本页、下一页、最后一页的链接;以及分页信息。
3.2 事件监听
REST
提供了8个基于 Repository
的事件,如下:
BeforeCreateEvent AfterCreateEvent BeforeSaveEvent AfterSaveEvent BeforeLinkSaveEvent AfterLinkSaveEvent BeforeDeleteEvent AfterDeleteEvent
添加一个自定义事件如下:
package com.pkslow.rest.event; import com.pkslow.rest.entity.User; import org.springframework.data.rest.core.event.AbstractRepositoryEventListener; import org.springframework.stereotype.Component; @Component public class PkslowEventListener extends AbstractRepositoryEventListener { @Override public void onBeforeCreate(User entity) { System.out.println("pkslow creating:" + entity); } @Override public void onBeforeSave(User entity) { System.out.println("pkslow saving:" + entity); } @Override public void onAfterDelete(User entity) { System.out.println("pkslow deleted:" + entity); } }
分别执行了增加、修改、删除后,日志如下:
pkslow creating:User{id=null, name='pkslow.com', age=18, email='pkslow@pkslow.com'} pkslow saving:User{id=32, name='pkslow.com', age=20, email='pkslow@pkslow.com'} pkslow deleted:User{id=14, name='pkslow.com', age=18, email='pkslow@pkslow.com'}
说明事件成功执行,结合这个功能,可以实现很多业务逻辑,如删除后记录操作日志,并删除其它相关数据。
3.3 路径
默认基础路径是 /
,可以通过 spring.data.rest.base-path=api
进行配置,这样就变成了 localhost:8080/api/user
。
4 总结
本文介绍了 Spring Data REST
,可以方便大家进行 RESTful
服务开发。但据了解,项目中使用的并不多,简单学习一下,不失是一种了解 Spring
全家桶及架构理念的方式。
参考文档:
欢迎关注微信公众号< 南瓜慢说 >,将持续为你更新…