2

I'm using Spring Boot, Spring Data REST, Spring HATEOAS, Hibernate, JPA.

I'm using extensively Spring Data REST in my application and I expose all Repositories of my entities. Unfortunately there are some particular cases that are not so easy to manage. One of that is this:

I've a custom controller:

@Api(tags = "CreditTransfer Entity")
@RepositoryRestController
@RequestMapping(path = "/api/v1")
@PreAuthorize("isAuthenticated()")
public class CreditTransferController {

@RequestMapping(method = RequestMethod.GET, path = "/creditTransfers/{id}")
    public ResponseEntity<?> findAll(@PathVariable("id") long id, HttpServletRequest request, Locale locale,
            PersistentEntityResourceAssembler resourceAssembler) {
        //my code

    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/creditTransfers/{id}")
    public ResponseEntity<?> deleteMovement(@PathVariable("id") long id, HttpServletRequest request, Locale locale,
            PersistentEntityResourceAssembler resourceAssembler) {
        //my code
    }

The problem here is that overriding these endpoints, I am hiding the /search endpoint that Spring Data REST create. And that is very important to me.

I did't find any smart way to make this to work without interfer with defaults endpoints provided from Spring Data REST.

Is there a way to solve my problem?

======================================================================

A small enhancement is using a mapping like this:

@RequestMapping(method = RequestMethod.DELETE, path = "/creditTransfers/{id:[0-9]+}")

In this way my controller doesn't catch the url localhost:8080/api/v1/creditTransfers/search but still, if I override just the DELETE method, when I try to GET localhost:8080/api/v1/creditTransfers I've the error Request method 'GET' not supported. Seems my controller override ALL methods for a specific path and not just the one I set.

drenda
  • 5,846
  • 11
  • 68
  • 141
  • you want to override repository urls not through the controller right ? – Amr Alaa Nov 29 '17 at 16:38
  • @AmrAlaa I need to override the implementation as well. Actually I needed to override the implementation of the DELETE. The url is the SAME the default repository managed from Spring Data REST provide. And that is the problem. – drenda Nov 29 '17 at 16:40

2 Answers2

2

As explained in this thread, and originally here, if you annotate your controller with @RepositoryRestController AND @RequestMapping, you lose the benefit of Spring generating the "default" REST endpoints for you. The only way to prevent this, i.e. to get both the automatically generated endpoints and your custom endpoints, is to use method-level requestmapping only:

@Api(tags = "CreditTransfer Entity")
@RepositoryRestController
@PreAuthorize("isAuthenticated()")
public class CreditTransferController {

    @GetMapping("/api/v1/creditTransfers/{id}")
    public ResponseEntity<?> findAll(@PathVariable("id") long id, HttpServletRequest request, Locale locale,
            PersistentEntityResourceAssembler resourceAssembler) {
        //my code

    }

    @DeleteMapping("/api/v1/creditTransfers/{id}")
    public ResponseEntity<?> deleteMovement(@PathVariable("id") long id, HttpServletRequest request, Locale locale,
            PersistentEntityResourceAssembler resourceAssembler) {
        //my code
    }

}

Side note: I also used the mapping shortcuts GetMapping and DeleteMapping.

Marc Tarin
  • 3,109
  • 17
  • 49
0

You can add the

@RestResource(exported=false)

over the methods that you want to override in the repository.

Amr Alaa
  • 545
  • 3
  • 7
  • Unfortunately even using that annotation doesn't resolve my problem. In fact if I try to access to http://localhost:8080/api/v1/creditTransfers/search I've a PageNotFound:252 - Request method 'GET' not supported. I guess this because my controller take the precedence to the Spring Data REST because path = "/creditTransfers/{id}" of DELETE method (my method) match the url http://localhost:8080/api/v1/creditTransfers/search – drenda Nov 29 '17 at 16:54