Mapping controller endpoints to Spring JPA layer

杀马特。学长 韩版系。学妹 提交于 2021-01-29 16:12:32

问题


I've written this request mapping to access a ticket by it's id with the optional request parameters ticketType & ticketStatus :

@GetMapping(path = "/tickets/{ticketId}")
   @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity<List<TicketResponse>> getTicketsById(@PathVariable("ticketId") final Long ticketId, @RequestParam("ticketType") final String ticketType, @RequestParam("ticketStatus") final String ticketStatus)

Currently the repository contains methods for returning based on either the ticketId or the ticketState :

    @Repository
    public interface TicketRepository extends JpaRepository<TicketEntity, Long> {

Stream<TicketEntity> findByTicketIdAndTicketState(@Param("ticketId") Long ticketId);

Stream<TicketEntity> findByTicketIdAndTicketState(@Param("ticketId") Long ticketId, @Param("ticketState") String ticketState);

    }

How should these endpoints be exposed at the controller layer ?

Currently the endpoint is:

@GetMapping(path = "/{ticketId}")
    @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity<List<TicketResponse>> getTicketsByTicketId(
            @PathVariable("productId") final Long ticketId, @RequestParam(name = "ticketState", required=false) final String ticketState) {

        final List<TicketResponse> ticketsByTicketId = ticketService.getTicketsByTicketId(ticketId);

        if(ticketsByTicketId.size() == 0){
            return ResponseEntity.ok("No tickets found");
        }
        else {
            return ResponseEntity.ok(ticketsByTicketId);
        }

    }

Should I add a new endpoint? :

Or update the controller to select which JPA repository method to implement depending on the query ?:

@GetMapping(path = "/{ticketId}")
    @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity<List<TicketResponse>> getTicketsByTicketId(
            @PathVariable("productId") final Long ticketId, @RequestParam(name = "ticketState", required=false) final String ticketState) {

List<TicketResponse> tickets = null;

if(ticketState == null) {
        tickets = ticketService.getTicketsByTicketId(ticketId);
}
else{
tickets = ticketService.getTicketsByTicketIdAndTicketState(ticketId, ticketState);
}

        if(ticketsByTicketId.size() == 0){
            return ResponseEntity.ok("No tickets found");
        }
        else {
            return ResponseEntity.ok(ticketsByTicketId);
        }

    }

The JPA repository will be extended further to filter based on many more parameters such as ticketType, ticketDescription . I just mention this as my controller logic will get very complicated if is required to check which parameter is null and the select the relevant JPA query.


回答1:


Using Spring Data JPA Specification this map filtering problem can be solved. Complex queries can be build using the Criteria API depends on the filtering parameter.

A good article about JPA Specification



来源:https://stackoverflow.com/questions/61041979/mapping-controller-endpoints-to-spring-jpa-layer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!