Spring 数据 REST 高级资源
Spring data REST advanced resources
我只是为我的应用程序实现 REST 端点,我不确定哪种方式是最佳实践。
我正在以这种方式获取我所有的实体
@GetMapping("/offers")
@Timed
public ResponseEntity<List<Offer>> getAllOffers(@ApiParam Pageable pageable)
throws URISyntaxException {
log.debug("REST request to get a page of Offers");
Page<Offer> page = offerService.findAll(pageable);
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/offers");
return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
}
但是我该怎么办,例如,如果我只想要具有某些特定 projectId 的报价。
@Query("FROM Offer o WHERE o.project.id = :projectId")
List<Offer> findAllByProject(@Param("projectId") Long projectId);
Q1 这个存储库调用的 REST 方法应该是什么样子的?正确的映射路径或参数插入是什么。
Q2 如果我想创建更复杂的查询怎么办?例如,根据地区、薪水等条件获取offer?
我知道我能以某种方式做到这一点,但我正在寻找一种干净的代码方式。我想让我的代码保持干净、可扩展和可持续。 主要是我想遵循 REST 的规则。
使用 spring 数据 jpa,您可以使用查询方法来编写相当复杂的查询。参考 here.
我看到你正在使用我从未使用过的 swagger 注释 (@ApiParam),但是在 Spring 中,如果你还没有这样做,请用 @RestController 标记你的控制器。
@RestController
public class OfferRestController {
.....
您可以像这样定义您的端点 - 如果您使用 Spring 引导,并且在您的类路径中有 jackson,它将为您处理序列化;
@GetMapping(value="/offers")
public List<Offer> getAllOffers() {
return offerService.findAll(pageable);
}
@GetMapping(value="/offers/{location})
public List<Offer> getAllOffers(@PathVariable("location") String location) {
return offerService.findByLocation(location);
}
很高兴您了解 JPA 存储库,您见过 Spring RestRepositories 吗?他们通过 REST 自动公开您的查询
interface OfferRepository extends CrudRepository<Offer,Long> {
List<Offer> findByLocation (final String location)
}
会公开这样的端点;
http://localhost:8080/offers/search/findByLocation?location=London
您将需要 spring 启动器,spring-boot-starter-data-jpa,spring-boot-starter-data-rest 和 spring-data-rest-hal-browser 将允许您通过浏览器浏览您的 REST 存储库 (Spring starter guide)。
我不敢提供示例 (!),但要构建更高级的查询,您可以通过查询提供自定义实现 Specification
[编辑]
primarily I want to follow the rules of REST.
您还有@PostMapping、@DeleteMapping、@PutMapping,它们的工作方式类似于@GetMapping 并映射到相应的HTTP 动词;你会 post 这样;
@PostMapping ("/offers")
public void postSomething (@RequestBody Offer offer) {
offerService.save (offer);
}
您可以注入您的存储库类型的 bean。 Spring 生成一个完全配置的代理实例并将其定位在上下文中。如果导出,您可以指定存储库中定义的操作的路径:
@RepositoryRestResource(exported = true, path = "path-to-repository")
要设置操作的路径,可以在方法上放置 @RestResource
注释:
@RestResource(exported = true, path = "operation")
默认情况下,它将在 path-to-repository/search/operation
后可用。
使用 @Query
和 JPQ 语言编写自定义查询,或者使用本机语言进行更详细的控制 SQL:
@Query(value = "...", nativeQuery = true)
实际上,由于其复杂性,存储库很难实现某些操作。它可能会产生太大的默认方法,这些默认方法处理一些存储库方法以产生所需的输出。
解决方案是创建一对控制器和服务,它们将 "copy" 并补充存储库的工作。幸运的是,Spring 提供了制作 projection/sort/pagination 和存储库开箱即用的其他东西的方法。
我只是为我的应用程序实现 REST 端点,我不确定哪种方式是最佳实践。
我正在以这种方式获取我所有的实体
@GetMapping("/offers")
@Timed
public ResponseEntity<List<Offer>> getAllOffers(@ApiParam Pageable pageable)
throws URISyntaxException {
log.debug("REST request to get a page of Offers");
Page<Offer> page = offerService.findAll(pageable);
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/offers");
return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
}
但是我该怎么办,例如,如果我只想要具有某些特定 projectId 的报价。
@Query("FROM Offer o WHERE o.project.id = :projectId")
List<Offer> findAllByProject(@Param("projectId") Long projectId);
Q1 这个存储库调用的 REST 方法应该是什么样子的?正确的映射路径或参数插入是什么。
Q2 如果我想创建更复杂的查询怎么办?例如,根据地区、薪水等条件获取offer?
我知道我能以某种方式做到这一点,但我正在寻找一种干净的代码方式。我想让我的代码保持干净、可扩展和可持续。 主要是我想遵循 REST 的规则。
使用 spring 数据 jpa,您可以使用查询方法来编写相当复杂的查询。参考 here.
我看到你正在使用我从未使用过的 swagger 注释 (@ApiParam),但是在 Spring 中,如果你还没有这样做,请用 @RestController 标记你的控制器。
@RestController
public class OfferRestController {
.....
您可以像这样定义您的端点 - 如果您使用 Spring 引导,并且在您的类路径中有 jackson,它将为您处理序列化;
@GetMapping(value="/offers")
public List<Offer> getAllOffers() {
return offerService.findAll(pageable);
}
@GetMapping(value="/offers/{location})
public List<Offer> getAllOffers(@PathVariable("location") String location) {
return offerService.findByLocation(location);
}
很高兴您了解 JPA 存储库,您见过 Spring RestRepositories 吗?他们通过 REST 自动公开您的查询
interface OfferRepository extends CrudRepository<Offer,Long> {
List<Offer> findByLocation (final String location)
}
会公开这样的端点;
http://localhost:8080/offers/search/findByLocation?location=London
您将需要 spring 启动器,spring-boot-starter-data-jpa,spring-boot-starter-data-rest 和 spring-data-rest-hal-browser 将允许您通过浏览器浏览您的 REST 存储库 (Spring starter guide)。
我不敢提供示例 (!),但要构建更高级的查询,您可以通过查询提供自定义实现 Specification
[编辑]
primarily I want to follow the rules of REST.
您还有@PostMapping、@DeleteMapping、@PutMapping,它们的工作方式类似于@GetMapping 并映射到相应的HTTP 动词;你会 post 这样;
@PostMapping ("/offers")
public void postSomething (@RequestBody Offer offer) {
offerService.save (offer);
}
您可以注入您的存储库类型的 bean。 Spring 生成一个完全配置的代理实例并将其定位在上下文中。如果导出,您可以指定存储库中定义的操作的路径:
@RepositoryRestResource(exported = true, path = "path-to-repository")
要设置操作的路径,可以在方法上放置
@RestResource
注释:@RestResource(exported = true, path = "operation")
默认情况下,它将在
path-to-repository/search/operation
后可用。使用
@Query
和 JPQ 语言编写自定义查询,或者使用本机语言进行更详细的控制 SQL:@Query(value = "...", nativeQuery = true)
实际上,由于其复杂性,存储库很难实现某些操作。它可能会产生太大的默认方法,这些默认方法处理一些存储库方法以产生所需的输出。
解决方案是创建一对控制器和服务,它们将 "copy" 并补充存储库的工作。幸运的是,Spring 提供了制作 projection/sort/pagination 和存储库开箱即用的其他东西的方法。