SpringBoot构建REST服务(转载)
作者:互联网
参考:
https://blog.csdn.net/ZhangCurie/article/details/118638225
https://blog.csdn.net/fatalflower/article/details/112380594
一、概述
有时候我们在面向资源编程时资源有很多操作,但是暴露给调用者的api都是孤立的。
使用RESTful的开发风格,支持我们将对资源的操作状态转移关联起来。
举一个具体的例子,我们有一个地图,地图上要显示一些点位,点击点位可以显示当前点位的详细信息。
那我们至少应该有两个接口,比如:
getMapPointList();//点位列表 getMapPointDetail(String pid);//点位详情
那么当前端调用者看到第一个接口时,他可能想要知道某个具体点位的详情信息如何获取。
如果依照我们之前的开发方式,他应该去翻swagger文档,根据API名称再加上自己的经验得到第二个接口。
返回来一样,如果有新来了一个开发人员,他需要根据点位详情在前端做一些调整。但是这个接口需要传入一个参数pid,pid是什么,从哪里来,他不知道。
RESTful开发风格,建议我们将某个资源相关的所有连接在接口中给出来。让调用者不用再去翻文档就可以知道针对这个资源的所有操作。
二、实战
其实在接口中硬编码上相关的link也是可以的,但会增加我们的工作量。
还好有一个现成的工具可以。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-hateoas</artifactId> </dependency>
如果和swagger一起使用,可能会报错。
Parameter 0 of method linkDiscoverers in org.springframework.hateoas.config.HateoasConfiguration
这个时候需要增加一个配置信息。
@Bean public LinkDiscoverers discoverers() { List<LinkDiscoverer> plugins = new ArrayList<>(); plugins.add(new CollectionJsonLinkDiscoverer()); return new LinkDiscoverers(SimplePluginRegistry.create(plugins)); }
好了,假如我们现在有一个资源叫做Metadata,我们需要在这个实体类上继承一个类RepresentationModel,类内部什么也不需要做。
@Data @AllArgsConstructor @NoArgsConstructor @Table(name = "metadata") public class Metadata extends RepresentationModel<Metadata> implements Serializable { private static final long serialVersionUID = 5536708482983535120L; @ApiModelProperty("uid:唯一标识") private String uid; @ApiModelProperty("名称") private String name; //... }
针对这个资源,我们可以一次性返回一个资源list.controller代码如下:
@ApiOperation("获取所有元数据") @GetMapping("metadatas") public BaseResponse<List<Metadata>> metadatas() { List<Metadata> metaDatas = metadataService.getMetaData(); return BaseResponse.success(metaDatas); }
postman执行一下,显示如下
我们拿到了metadata的资源list,然并软,可以在这些资源上做什么操作呢?不知道!
当然,后端自己是知道的,因为操作都写在代码里。那这些怎么能让外部调用者知道呢?
/** * 使用指定UID获取一个Metadata对象 * * @param uid * @return */ @ApiOperation("获取元数据") @GetMapping("metadata") public BaseResponse<Metadata> getMetadata(@RequestParam String uid) { Metadata byUid = metadataService.getByUid(uid); byUid.add(linkTo(methodOn(MetadataController.class).getMetadata(uid)).withSelfRel().withType("GET")); byUid.add(linkTo(methodOn(MetadataController.class).metadatas()).withRel("metadatas").withType("GET")); return BaseResponse.success(byUid); } /** * 新建一个Metadata,底层实现replace into * * @param obj * @return */ @EventPoint @ApiOperation("添加元数据") @PostMapping("metadata") public BaseResponse<Void> addMetadata(@RequestBody Metadata obj) { metadataService.addMetadata(obj); return BaseResponse.success(null); } /** * 更新一个metadata,底层实现update * * @param obj * @return */ @EventPoint @ApiOperation("更新元数据") @PutMapping("updateMetadata") public BaseResponse<Void> updateMetadata(@RequestBody Metadata obj) { metadataService.updateMetadata(obj); return BaseResponse.success(null); } @EventPoint @ApiOperation("删除元数据") @DeleteMapping("deleteMetadata") public BaseResponse<Void> deleteMetadata(@RequestParam String uid) { metadataService.deleteMetadata(uid); return BaseResponse.success(null); }
基于hateoas,我们只需要修改一下metadatas的代码,即可将这个资源的所有操作暴露给前端调用者。
@ApiOperation("获取所有元数据") @GetMapping("metadatas") public BaseResponse<List<Metadata>> metadatas() { List<Metadata> metaDatas = metadataService.getMetaData(); for (Metadata metaData : metaDatas) { metaData.add(linkTo(methodOn(MetadataController.class).getMetadata(metaData.getUid())).withRel("metadata").withType("GET")); metaData.add(linkTo(methodOn(MetadataController.class).addMetadata(metaData)).withRel("metadata").withType("POST")); metaData.add(linkTo(methodOn(MetadataController.class).updateMetadata(metaData)).withRel("updateMetadata").withType("PUT")); metaData.add(linkTo(methodOn(MetadataController.class).deleteMetadata(metaData.getUid())).withRel("deleteMetadata").withType("DELETE")); } return BaseResponse.success(metaDatas); }
postman再执行一下,可以看到,除了元数据原有的信息之外,还多了其他的link信息。
标签:return,SpringBoot,BaseResponse,Metadata,REST,uid,转载,public,metaData 来源: https://www.cnblogs.com/wangbin2188/p/16418878.html