RESTful服务

RESTful服务

在移动互联网中,RESTful 得到了非常广泛的使用。RESTful 这个概念提出来很早,但是以前没有移动互联网时,我们做的大部分应用都是前后端不分的,在这种架构的应用中,数据基本上都是在后端渲染好返回给前端展示的,此时 RESTful 在 Web 应用中基本就没用武之地,移动互联网的兴起,让我们一套后台对应多个前端项目,因此前后端分离,RESTful 顺利走上前台。

Spring Boot 继承自 Spring + SpringMVC, SpringMVC 中对于 RESTful 支持的特性在 Spring Boot 中全盘接收,同时,结合 Jpa 和 自动化配置,对于 RESTful 还提供了更多的支持,使得开发者几乎不需要写代码(很少几行),就能快速实现一个 RESTful 风格的增删改查。

创建项目

引入依赖如下:

image

配置DataSource和JPA

创建实体类

@Data
@Entity(name="t_book")
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String author;
}
public interface BookDao extends JpaRepository<Book,Integer> {
}

这里一个是配置了一个实体类 Book,另一个则是配置了一个 BookRepository ,项目启动成功后,框架会根据 Book 类的定义,在数据库中自动创建相应的表,BookRepository 接口则是继承自 JpaRepository ,JpaRepository 中自带了一些基本的增删改查方法。

测试

启动项目进行测试了,使用POSTMAN来测试。

此时我们的项目已经默认具备了一些接口:

  • 根据 id 查询接口

http://localhost:8080/books/{id}

  • 分页查询

http://localhost:8080/books

这是一个批量查询接口,默认请求路径是类名首字母小写,并且再加一个 s 后缀。这个接口实际上是一个分页查询接口,没有传参数,表示查询第一页,每页 20 条数据。查询结果中,除了该有的数据之外,也包含了分页数据:

image

分页数据中:

  • size 表示每页查询记录数

  • totalElements 表示总记录数

  • totalPages 表示总页数

  • number 表示当前页数,从0开始计

  • 如果要分页或者排序查询,可以使用 _links 中的链接。http://localhost:8080/books?page=1&size=3&sort=id,desc

  • 添加

也可以添加数据,添加是 POST 请求,数据通过 JSON 的形式传递

image
image
  • 修改

修改接口默认也是存在的,数据修改请求是一个 PUT 请求,修改的参数也是通过 JSON 的形式传递

image
  • 删除

当然也可以通过 DELETE 请求根据 id 删除数据

image

删除成功后,是没有返回值的。

不需要几行代码,一个基本的增删改查就有了。

这些都是默认的配置,这些默认的配置实际上都是在 JpaRepository 的基础上实现的,实际项目中,我们还可以对这些功能进行定制。

自定义查询

查询定制
。对于查询的定制,只需要在dao中提供相关的方法即可。命名方法见JPA一文中的表格。自定义的方法,参数要有 @Param 注解。例如根据作者查询书籍:

public interface BookRepository extends JpaRepository<Book,Long> {
    List<Book> findBookByAuthorContaining(@Param("author") String author);
}

定制完成后,重启项目,此时就多了一个查询接口,开发者可以通过 http://localhost:8080/books/search 来查看和 book 相关的自定义接口都有哪些,接口名就是方法名。

但是,这样有一个缺陷,就是 Jpa 中方法名太长,因此,如果不想使用方法名作为接口名,则可以使用@RestResource注解自定义接口名:

public interface BookRepository extends JpaRepository<Book, Long> {
    @RestResource(rel = "byauthor",path = "byauthor")
    List<Book> findBookByAuthorContaining(@Param("author") String author);
}

@RestResource 注解中,两个参数的含义:

  • rel 表示接口查询中,这个方法的 key
  • path 表示请求路径
    定义完成后,表示接口名为 byauthor ,重启项目,继续查询接口:
image

除了 rel 和 path 两个属性之外,@RestResource 中还有一个属性,exported 表示是否暴露接口,默认为 true ,表示暴露接口,即方法可以在前端调用,如果仅仅只是想定义一个方法,不需要在前端调用这个方法,可以设置 exported 属性为 false 。

如果不想暴露官方定义好的方法,例如根据 id 删除数据,只需要在自定义接口中重写该方法,然后在该方法上加 @RestResource 注解并且配置相关属性即可。

另外生成的 JSON 字符串中的集合名和单个 item 的名字都是可以自定义的:

@RepositoryRestResource(collectionResourceRel = "bs",itemResourceRel = "b",path = "bs")
public interface BookRepository extends JpaRepository<Book, Long> {
    @RestResource(rel = "byauthor",path = "byauthor")
    List<Book> findBookByAuthorContaining(@Param("author") String author);
    @Override
    @RestResource(exported = false)
    void deleteById(Long aLong);
}

path 属性表示请求路径,请求路径默认是类名首字母小写+s,可以在这里自己重新定义。

image

其他配置

最后,也可以在 application.properties 中配置 REST 基本参数:

spring.data.rest.base-path=/api
spring.data.rest.sort-param-name=sort
spring.data.rest.page-param-name=page
spring.data.rest.limit-param-name=size
spring.data.rest.max-page-size=20
spring.data.rest.default-page-size=0
spring.data.rest.return-body-on-update=true
spring.data.rest.return-body-on-create=true

配置含义,从上往下,依次是:

  1. 给所有的接口添加统一的前缀
  2. 配置排序参数的 key ,默认是 sort
  3. 配置分页查询时页码的 key,默认是 page
  4. 配置分页查询时每页查询页数的 key,默认是size
  5. 配置每页最大查询记录数,默认是 20 条
  6. 分页查询时默认的页码
  7. 更新成功时是否返回更新记录
  8. 添加成功时是否返回添加记录
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容