关于spring:2022就业季|Spring认证教你如何使用-Spring-构建-REST-服务三

41次阅读

共计 6597 个字符,预计需要花费 17 分钟才能阅读完成。

书接上文⬆⬆⬆是什么让一些货色变得 RESTful?到目前为止,您领有一个基于 Web 服务来解决波及员工数据的外围操作。但这还不足以让事件变得“RESTful”。丑陋的 URL/employees/ 3 不是 REST。仅应用 GET,POST 等不是 REST。安顿好所有的 CRUD 操作不当 REST。事实上,到目前为止,咱们构建的更好地形容为 RPC(近程过程调用)。那是因为没有方法晓得如何与这个服务器交互。如果您明天公布了此内容,您还必须编写文档或在某个中央托管开发人员的门户,其中蕴含所有详细信息。Roy Fielding 的这一陈说可能会进一步为 REST 和 RPC 之间的区别提供线索:我对将任何基于 HTTP 的接口称为 REST API 的人数感到丧气。明天的例子是 SocialSite REST API。那就是 RPC。它尖叫 RPC。展现的耦合太多了,应该给它一个 X 评级。要做些什么来应用 REST 架构格调分明地意识到超文本是一种束缚?换句话说,应用程序状态引擎(以及 API)不是由超文本驱动的,那么它就不能是 RESTful 并且不能是 REST API。期间。是否有一些损坏的手册须要修复?— 罗伊菲尔丁 https://roy.gbiv.com/untangle… 在咱们的示意中不包含超媒体的副作用是客户端必须硬编码 URI 来导航 API。这导致了与网络电子商务衰亡之前雷同的脆弱性。这表明咱们的 JSON 输入须要一点帮忙。介绍 Spring HATEOAS,这是一个 Spring 我的项目,旨在帮忙您编写超媒体驱动的输入。要将您的服务降级为 RESTful,请将其增加到您的构建中:将 Spring HATEOAS 增加 dependencies 到 pom.xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-hateoas</artifactId></dependency> 复制这个小型库将为咱们提供定义 RESTful 服务的构造,而后以可承受的格局出现它以供客户应用。任何 RESTful 服务的一个要害因素是增加指向相干操作的链接。要使您的控制器更加 RESTful,请增加如下链接:获取单个我的项目的资源 @GetMapping(“/employees/{id}”)EntityModel<Employee> one(@PathVariable Long id) {Employee employee = repository.findById(id) // .orElseThrow(() -> new EmployeeNotFoundException(id)); return EntityModel.of(employee, // linkTo(methodOn(EmployeeController.class).one(id)).withSelfRel(), linkTo(methodOn(EmployeeController.class).all()).withRel(“employees”));}本教程基于 Spring MVC 并应用动态辅助办法 WebMvcLinkBuilder 来构建这些链接。如果您在我的项目中应用 Spring WebFlux,则必须改用 WebFluxLinkBuilder. 这与咱们之前的状况十分类似,但有一些变动:该办法的返回类型已从 更改 Employee 为 EntityModel<Employee>。EntityModel<T> 是来自 Spring HATEOAS 的通用容器,它不仅蕴含数据,还蕴含链接汇合。linkTo(methodOn(EmployeeController.class).one(id)).withSelfRel()要求 Spring HATEOAS 建设到 EmployeeController’one()办法的链接,并将其标记为自链接。linkTo(methodOn(EmployeeController.class).all()).withRel(“employees”)要求 Spring HATEOAS 建设到聚合根的链接 all(),并将其称为“员工”。“建设链接”是什么意思?Spring HATEOAS 的外围类型之一是 Link. 它包含一个 URI 和一个 rel(关系)。链接是赋予网络势力的货色。在万维网之前,其余文档零碎会出现信息或链接,但正是将文档与这种关系元数据链接在一起,才将网络缝合在一起。Roy Fielding 激励应用使 Web 胜利的雷同技术构建 API,链接就是其中之一。如果您重新启动应用程序并查问 Bilbo 的员工记录,您将失去与之前略有不同的响应:冰壶更丑陋当你的 curl 输入变得更简单时,它可能变得难以浏览。应用这个或其余技巧来丑化 curl 返回的 json:# 批示局部将输入通过管道传输到 json_pp 并要求它使您的 JSON 更丑陋。(或者应用任何你喜爱的工具!)# v——————vcurl -v localhost:8080/employees/1 | json_pp 单个员工的 RESTful 示意 {“id”: 1,”name”: “Bilbo Baggins”,”role”: “burglar”,”_links”: {“self”: {“href”: “http://localhost:8080/employees/1″},”employees”: {“href”: “http://localhost:8080/employees”}}} 这个解压缩的输入不仅显示了您之前看到的数据元素(id 和 name)role,而且还显示了一个_links 蕴含两个 URI 的条目。整个文档应用 HAL 进行格式化。HAL 是一种轻量级媒体类型,它不仅能够编码数据,还能够编码超媒体控件,揭示消费者留神他们能够导航的 API 的其余局部。在这种状况下,有一个“自我”链接(有点像 this 代码中的语句)以及一个返回聚合根的链接。为了使聚合根 ALSO 更加 RESTful,您心愿包含顶级链接,同时还包含其中的任何 RESTful 组件。所以咱们把这个获取聚合根 @GetMapping(“/employees”)List<Employee> all() { return repository.findAll();}进入这个获取聚合本源 @GetMapping(“/employees”)CollectionModel<EntityModel<Employee>> all() { List<EntityModel<Employee>> employees = repository.findAll().stream() .map(employee -> EntityModel.of(employee, linkTo(methodOn(EmployeeController.class).one(employee.getId())).withSelfRel(), linkTo(methodOn(EmployeeController.class).all()).withRel(“employees”))) .collect(Collectors.toList()); return CollectionModel.of(employees, linkTo(methodOn(EmployeeController.class).all()).withSelfRel());}哇!已经的那个办法,repository.findAll()都长大了!不必放心。让咱们关上它。CollectionModel<> 是另一个 Spring HATEOAS 容器;它旨在封装资源汇合,而不是像 EntityModel<> 之前那样封装单个资源实体。CollectionModel<>,也能够让您蕴含链接。不要让第一个申明溜走。“封装汇合”是什么意思?员工珍藏?不齐全的。因为咱们议论的是 REST,它应该封装员工资源的汇合。这就是为什么您获取所有员工,而后将它们转换为 EntityModel<Employee> 对象列表的起因。(感激 Java 8 流!)如果您重新启动应用程序并获取聚合根,您能够看到它当初的样子。员工资源汇合的 RESTful 示意 { “_embedded”: { “employeeList”: [ { “id”: 1, “name”: “Bilbo Baggins”, “role”: “burglar”, “_links”: { “self”: { “href”: “http://localhost:8080/employees/1”}, “employees”: {“href”: “http://localhost:8080/employees”} } }, {“id”: 2, “name”: “Frodo Baggins”, “role”: “thief”, “_links”: { “self”: { “href”: “http://localhost:8080/employees/2”}, “employees”: {“href”: “http://localhost:8080/employees”} } } ] }, “_links”: {“self”: { “href”: “http://localhost:8080/employees”} }} 复制对于提供员工资源汇合的聚合根,有一个顶级“自我”链接。“汇合”列在“_embedded”局部下方;这就是 HAL 示意汇合的形式。并且汇合的每个独自成员都有他们的信息以及相干链接。增加所有这些链接有什么意义?它使得随着工夫的推移倒退 REST 服务成为可能。能够保护现有链接,而未来能够增加新链接。新客户能够利用新链接,而旧客户能够在旧链接上维持本人的生命。如果服务被从新定位和挪动,这将特地有用。只有放弃链接构造,客户端依然能够找到事物并与之交互。简化链接创立在后面的代码中,您是否留神到单个员工链接创立中的反复?为员工提供单个链接以及创立到聚合根的“员工”链接的代码显示了两次。如果这引起了您的关注,很好!有一个解决方案。简略地说,你须要定义一个将 Employee 对象转换为 EntityModel<Employee> 对象的函数。尽管您能够轻松地本人编写此办法,但在实现 Spring HATEOAS 的 RepresentationModelAssembler 接口的路线上也有益处——它将为您实现工作。进化 /src/main/java/payroll/EmployeeModelAssembler.javapackage payroll;import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;import org.springframework.hateoas.EntityModel;import org.springframework.hateoas.server.RepresentationModelAssembler;import org.springframework.stereotype.Component;@Componentclass EmployeeModelAssembler implements RepresentationModelAssembler<Employee, EntityModel<Employee>> {@Override public EntityModel<Employee> toModel(Employee employee) {return EntityModel.of(employee, // linkTo(methodOn(EmployeeController.class).one(employee.getId())).withSelfRel(), linkTo(methodOn(EmployeeController.class).all()).withRel(“employees”)); }}复制这个简略的接口有一个办法:toModel(). 它基于将非模型对象 ( Employee) 转换为基于模型的对象 (EntityModel<Employee>)。您之前在控制器中看到的所有代码都能够移到此类中。并且通过利用 Spring Framework 的 @Component 注解,将在应用程序启动时主动创立汇编程序。Spring HATEOAS 的所有模型的形象基类是 RepresentationModel. 然而为了简略起见,我倡议应用 EntityModel<T> 作为您的机制来轻松地将所有 POJO 包装为模型。要利用此汇编器,您只需 EmployeeController 通过在构造函数中注入汇编器来更改。将 EmployeeModelAssembler 注入控制器 @RestControllerclass EmployeeController {private final EmployeeRepository repository; private final EmployeeModelAssembler assembler; EmployeeController(EmployeeRepository repository, EmployeeModelAssembler assembler) {this.repository = repository; this.assembler = assembler;} …}从这里,您能够在单项员工办法中应用该汇编程序:应用汇编程序获取单项资源 @GetMapping(“/employees/{id}”)EntityModel<Employee> one(@PathVariable Long id) {Employee employee = repository.findById(id) // .orElseThrow(() -> new EmployeeNotFoundException(id)); return assembler.toModel(employee);}这段代码简直是一样的,除了不是在 EntityModel<Employee> 这里创立实例,而是将它委托给汇编器。兴许这看起来并不多。在聚合根控制器办法中利用雷同的货色更令人印象粗浅:应用汇编程序获取聚合根资源 @GetMapping(“/employees”)CollectionModel<EntityModel<Employee>> all() { List<EntityModel<Employee>> employees = repository.findAll().stream() // .map(assembler::toModel) // .collect(Collectors.toList()); return CollectionModel.of(employees, linkTo(methodOn(EmployeeController.class).all()).withSelfRel());}同样,代码简直雷同,然而您能够将所有 EntityModel<Employee> 创立逻辑替换为 map(assembler::toModel). 因为 Java 8 办法援用,插入它并简化您的控制器非常容易。Spring HATEOAS 的一个要害设计指标是让 The Right Thing™ 变得更容易。在这种状况下:将超媒体增加到您的服务中,而无需对事物进行硬编码。在这个阶段,您曾经创立了一个理论生成超媒体驱动内容的 Spring MVC REST 控制器!不讲 HAL 的客户端能够在应用纯数据时疏忽额定的位。应用 HAL 的客户能够浏览您受权的 API。但这并不是应用 Spring 构建真正的 RESTful 服务所需的惟一内容。…… 未完待续 ……#java##spring 认证 ##spring 认证## 程序员#2022 待业季|Spring 认证教你,如何应用 Spring 构建 REST 服务 2022 待业季|Spring 认证教你,如何应用 Spring 构建 REST 服务(二)

以上就是明天对于 Spring 的一些探讨,对你有帮忙吗?如果你有趣味深刻理解,欢送到 Spring 中国教育管理中心留言交换!

正文完
 0