I'm using Spring-boot-starter-data-jpa, in my RestController I want to return the Location of newly created object. Is there a way to reverse the @RequestMapping's and not hardcode how to build the URL?
@RestController
@ExposesResourceFor(BookInstance.class)
public class BookInstanceController {
@RequestMapping(value="/bookInstances", method=RequestMethod.POST)
ResponseEntity<BookInstance> createBookInstance(@RequestBody BookInstance bookInstance){
BookInstance createdBookInstance = bookInstanceRepository.save(bookInstance);
return ResponseEntity.created(**reverseURL(createdBookInstance)**);
// return new ResponseEntity<BookInstance>(createdBookInstance, HttpStatus.CREATED);
// return createdBookInstance;
}
}
I always see people hard-coding their URL construction in this function, which just leaves me without words....
Of course I also have a GET function in the same class (otherwise there wouldn't be anything to reverse)
@RequestMapping(value="/bookInstances/{id}", method=RequestMethod.GET)
ResponseEntity<?> findOne(@PathVariable("id") Long id){
BookInstance bookInstance = bookInstanceRepository.findOne(id);
if(bookInstance == null){
return ResponseEntity.notFound().build();
}
return new ResponseEntity<BookInstance>(bookInstance, HttpStatus.OK);
}
An alternative solution that uses a Resource assembler:
public class BookInstanceResource extends Resource<BookInstance> {
public BookInstanceResource(Book content, Link... links) {
super(content, links);
}
}
public class BookInstanceResourceAssembler extends ResourceAssemblerSupport<BookInstance, BookInstanceResource> {
public BookInstanceResourceAssembler() {
super(BookInstanceController.class, BookInstanceResource.class)
}
@Override
public BookInstanceResource toResource(BookInstance bookInstance) {
// linkTo requires the following static import:
// import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
ControllerLinkBuilder builder = linkTo(BookInstance.class).slash("bookInstances").slash(bookInstance);
return new BookInstanceResource(bookInstance,
builder.withSelfRel(),
builder.withRel("bookInstance");
}
}
In your controller class:
@Autowired
private BookInstanceResourceAssembler resourceAssembler;
@GetMapping(value = "/bookInstances/{id}")
ResponseEntity findOne(@PathVariable("id") Long id) {
BookInstance bookInstance = bookInstanceRepository.findOne(id);
if(bookInstance == null){
return ResponseEntity.notFound().build();
}
BookInstanceResource resource = resourceAssembler.toResource(bookInstance);
return ResponseEntity.created(URI.create(resource.getLink("self").getHref()))
.body(resource);
}