Reputation: 35
I want to add an extra link to a entity such as:
"_links": {
"self": {
"href": "http://localhost:8080/api/organizaciones"
},
"profile": {
"href": "http://localhost:8080/api/profile/organizaciones"
},
"search": {
"href": "http://localhost:8080/api/organizaciones/search"
},
"disable": {
"href": "http://localhost:8080/api/organizaciones/disable"
}
}
The idea behind this scenario is that I need to expose a soft delete via its own link within Organizacion entity... right now I'm only able to do:
http://localhost:8080/api/organizaciones/search/disable?id=100
in order to perform the soft delete. How can I achieve this the right way? Or is it my only alternative creating a controller?
Upvotes: 1
Views: 365
Reputation: 23150
I finally figured it out, I did what was mentioned by Alex in a comment.
I have to give credit to the father of spring-data-rest to @olivergieke I checked one of his examples, more precise: restbucks
First created the following component
@Component
@RequiredArgsConstructor
public class OrganizacionResourceProcessor implements ResourceProcessor<Resource<Organizacion>>{
private static final String DISABLE_REL = "deshabilitar";
private static final String ENABLE_REL = "habilitar";
private final @NonNull EntityLinks entityLinks;
@Override
public Resource<Organizacion> process(Resource<Organizacion> resource) {
Organizacion organizacion = resource.getContent();
if(organizacion.isEnabled()){
resource.add(entityLinks.linkForSingleResource(Organizacion.class, organizacion.getId()).slash(DISABLE_REL).withRel(DISABLE_REL));
}
if(organizacion.isDisabled()){
resource.add(entityLinks.linkForSingleResource(Organizacion.class, organizacion.getId()).slash(ENABLE_REL).withRel(ENABLE_REL));
}
return resource;
}
}
Then created the controller to support those two operations...
@RepositoryRestController
@RequestMapping("/organizaciones")
@ExposesResourceFor(Organizacion.class)
@RequiredArgsConstructor
@Slf4j
@Transactional
public class OrganizacionController {
private final @NonNull OrganizacionRepository organizacionRepository;
private final @NonNull EntityLinks entityLinks;
@GetMapping(value="/{id}/habilitar")
public ResponseEntity<?> desactivarOrganizacion(@PathVariable("id") Long id) {
Preconditions.checkNotNull(id);
Organizacion organizacion = organizacionRepository.findOne(id);
if(organizacion == null){
return new ResponseEntity<Void>(HttpStatus.NOT_FOUND);
}
organizacion.setEstado(Estado.DESHABILITADO);
Organizacion pOrg = this.organizacionRepository.save(organizacion);
HttpHeaders header = new HttpHeaders();
header.setLocation(this.entityLinks.linkForSingleResource(Organizacion.class, pOrg.getId()).toUri());//construimos el URL
return new ResponseEntity<Void>(header,HttpStatus.CREATED);
}
@GetMapping(value="/{id}/deshabilitar")
public ResponseEntity<?> activarOrganizacion(@PathVariable("id") Long id){
Preconditions.checkNotNull(id);
Organizacion organizacion = organizacionRepository.findOne(id);
if(organizacion == null){
return new ResponseEntity<Void>(HttpStatus.NOT_FOUND);
}
organizacion.setEstado(Estado.ACTIVO);
Organizacion pOrg = this.organizacionRepository.save(organizacion);
HttpHeaders header = new HttpHeaders();
header.setLocation(this.entityLinks.linkForSingleResource(Organizacion.class, pOrg.getId()).toUri());//construimos el URL
return new ResponseEntity<Void>(header,HttpStatus.CREATED);
}
}
and that was it.
This was originally added to Revision 3 of the question.
Upvotes: 0
Reputation: 2322
You just need to add a class extending the ResourceProcessor interface and add it to the spring-context(http://docs.spring.io/spring-data/rest/docs/current/reference/html/#_the_resourceprocessor_interface) For example
@Bean
public ResourceProcessor<Resource<Person>> personProcessor() {
return new ResourceProcessor<Resource<Person>>() {
@Override
public Resource<Person> process(Resource<Person> resource) {
resource.add(new Link("http://localhost:8080/people", "added-link"));
return resource;
}
};
}
Where the Person entity can be replaced with your Organizacion entity.
Upvotes: 1