@GetMapping("/employees") ResponseEntity<Resources<Resource<Employee>>> findAll() { List<Resource<Employee>> employeeResources = StreamSupport.stream(repository.findAll().spliterator(), false) .map(employee -> new Resource<>(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, employee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(employee.getId()))), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees") )) .collect(Collectors.toList()); return ResponseEntity.ok(new Resources<>(employeeResources, linkTo(methodOn(EmployeeController.class).findAll()).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).newEmployee(null))))); }
@GetMapping(value = "/", produces = MediaTypes.HAL_JSON_VALUE) public ResourceSupport root() { ResourceSupport rootResource = new ResourceSupport(); rootResource.add( linkTo(methodOn(EmployeeController.class).root()).withSelfRel(), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees")); return rootResource; }
/** * Look up all employees, and transform them into a REST collection resource. * Then return them through Spring Web's {@link ResponseEntity} fluent API. * * NOTE: cURL will fetch things as HAL JSON directly, but browsers issue a different * default accept header, which allows XML to get requested first, so "produces" * forces it to HAL JSON for all clients. */ @GetMapping(value = "/employees", produces = MediaTypes.HAL_JSON_VALUE) ResponseEntity<Resources<Resource<Employee>>> findAll() { List<Resource<Employee>> employees = StreamSupport.stream(repository.findAll().spliterator(), false) .map(employee -> new Resource<>(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel(), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees"))) .collect(Collectors.toList()); return ResponseEntity.ok( new Resources<>(employees, linkTo(methodOn(EmployeeController.class).findAll()).withSelfRel())); }
@GetMapping("/") ResponseEntity<ResourceSupport> root() { ResourceSupport resourceSupport = new ResourceSupport(); resourceSupport.add(linkTo(methodOn(RootController.class).root()).withSelfRel()); resourceSupport.add(linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees")); resourceSupport.add(linkTo(methodOn(EmployeeController.class).findAllDetailedEmployees()).withRel("detailedEmployees")); resourceSupport.add(linkTo(methodOn(ManagerController.class).findAll()).withRel("managers")); return ResponseEntity.ok(resourceSupport); }
@PostMapping("/employees") public ResponseEntity<Resource<Employee>> newEmployee(@RequestBody Employee employee) { Employee savedEmployee = repository.save(employee); return ResponseEntity .created(savedEmployee.getId() .map(id -> linkTo(methodOn(EmployeeController.class).findOne(id)).toUri()) .orElseThrow(() -> new RuntimeException("Failed to create for some reason"))) .body(assembler.toResource(savedEmployee)); }
/** * Define links to add to every individual {@link Resource}. * * @param resource */ @Override protected void addLinks(Resource<EmployeeWithManager> resource) { resource.add(linkTo(methodOn(EmployeeController.class).findDetailedEmployee(resource.getContent().getId())).withSelfRel()); resource.add(linkTo(methodOn(EmployeeController.class).findOne(resource.getContent().getId())).withRel("summary")); resource.add(linkTo(methodOn(EmployeeController.class).findAllDetailedEmployees()).withRel("detailedEmployees")); }
/** * Define links to add to every {@link Resource}. * * @param resource */ @Override protected void addLinks(Resource<Employee> resource) { /** * Add some custom links to the default ones provided. * * NOTE: To replace default links, don't invoke {@literal super.addLinks()}. */ super.addLinks(resource); resource.getContent().getId() .ifPresent(id -> { // Add additional links resource.add(linkTo(methodOn(ManagerController.class).findManager(id)).withRel("manager")); resource.add(linkTo(methodOn(EmployeeController.class).findDetailedEmployee(id)).withRel("detailed")); // Maintain a legacy link to support older clients not yet adjusted to the switch from "supervisor" to "manager". resource.add(linkTo(methodOn(SupervisorController.class).findOne(id)).withRel("supervisor")); }); }
/** * Define links to add to {@link Resources} collection. * * @param resources */ @Override protected void addLinks(Resources<Resource<Employee>> resources) { super.addLinks(resources); resources.add(linkTo(methodOn(EmployeeController.class).findAllDetailedEmployees()).withRel("detailedEmployees")); resources.add(linkTo(methodOn(ManagerController.class).findAll()).withRel("managers")); resources.add(linkTo(methodOn(RootController.class).root()).withRel("root")); } }
/** * Look up a single {@link Employee} and transform it into a REST resource. Then return it through * Spring Web's {@link ResponseEntity} fluent API. * * See {@link #findAll()} to explain {@link GetMapping}'s "produces" argument. * * @param id */ @GetMapping(value = "/employees/{id}", produces = MediaTypes.HAL_JSON_VALUE) ResponseEntity<Resource<Employee>> findOne(@PathVariable long id) { return repository.findById(id) .map(employee -> new Resource<>(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel(), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees"))) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); }
/** * Retain default links for the entire collection, but add extra custom links for the {@link Manager} collection. * * @param resources */ @Override protected void addLinks(Resources<Resource<Manager>> resources) { super.addLinks(resources); resources.add(linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees")); resources.add(linkTo(methodOn(EmployeeController.class).findAllDetailedEmployees()).withRel("detailedEmployees")); resources.add(linkTo(methodOn(RootController.class).root()).withRel("root")); } }
@PostMapping("/employees") public ResponseEntity<Resource<Employee>> newEmployee(@RequestBody Employee employee) { Employee savedEmployee = repository.save(employee); return savedEmployee.getId() .map(id -> ResponseEntity .created(linkTo(methodOn(EmployeeController.class).findOne(id)).toUri()) .body(assembler.toResource(savedEmployee))) .orElse(ResponseEntity.notFound().build()); }
@GetMapping("/employees/{id}") ResponseEntity<Resource<Employee>> findOne(@PathVariable long id) { return repository.findById(id) .map(employee -> new Resource<>(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, employee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(employee.getId()))), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees") )) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); }
/** * Define links to add to the {@link Resources} collection. * * @param resources */ @Override protected void addLinks(Resources<Resource<EmployeeWithManager>> resources) { resources.add(linkTo(methodOn(EmployeeController.class).findAllDetailedEmployees()).withSelfRel()); resources.add(linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees")); resources.add(linkTo(methodOn(ManagerController.class).findAll()).withRel("managers")); resources.add(linkTo(methodOn(RootController.class).root()).withRel("root")); } }
@PostMapping("/employees") ResponseEntity<?> newEmployee(@RequestBody Employee employee) { try { Employee savedEmployee = repository.save(employee); Resource<Employee> employeeResource = new Resource<>(savedEmployee, linkTo(methodOn(EmployeeController.class).findOne(savedEmployee.getId())).withSelfRel()); return ResponseEntity .created(new URI(employeeResource.getRequiredLink(Link.REL_SELF).getHref())) .body(employeeResource); } catch (URISyntaxException e) { return ResponseEntity.badRequest().body("Unable to create " + employee); } }
@GetMapping(value = "/", produces = MediaTypes.HAL_JSON_VALUE) public ResourceSupport root() { ResourceSupport rootResource = new ResourceSupport(); rootResource.add( linkTo(methodOn(EmployeeController.class).root()).withSelfRel(), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees")); return rootResource; }
@PostMapping("/employees") ResponseEntity<?> newEmployee(@RequestBody Employee employee) { Employee savedEmployee = repository.save(employee); return new Resource<>(savedEmployee, linkTo(methodOn(EmployeeController.class).findOne(savedEmployee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, savedEmployee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(savedEmployee.getId()))), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees") ).getId() .map(Link::getHref) .map(href -> { try { return new URI(href); } catch (URISyntaxException e) { throw new RuntimeException(e); } }) .map(uri -> ResponseEntity.noContent().location(uri).build()) .orElse(ResponseEntity.badRequest().body("Unable to create " + employee)); }
/** * Update existing employee then return a Location header. * * @param employee * @param id * @return */ @PutMapping("/employees/{id}") ResponseEntity<?> updateEmployee(@RequestBody Employee employee, @PathVariable long id) { Employee employeeToUpdate = employee; employeeToUpdate.setId(id); repository.save(employeeToUpdate); Link newlyCreatedLink = linkTo(methodOn(EmployeeController.class).findOne(id)).withSelfRel(); try { return ResponseEntity.noContent() .location(new URI(newlyCreatedLink.getHref())) .build(); } catch (URISyntaxException e) { return ResponseEntity.badRequest().body("Unable to update " + employeeToUpdate); } }
@PutMapping("/employees/{id}") ResponseEntity<?> updateEmployee(@RequestBody Employee employee, @PathVariable long id) { Employee employeeToUpdate = employee; employeeToUpdate.setId(id); Employee updatedEmployee = repository.save(employeeToUpdate); return new Resource<>(updatedEmployee, linkTo(methodOn(EmployeeController.class).findOne(updatedEmployee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, updatedEmployee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(updatedEmployee.getId()))), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees") ).getId() .map(Link::getHref) .map(href -> { try { return new URI(href); } catch (URISyntaxException e) { throw new RuntimeException(e); } }) .map(uri -> ResponseEntity.noContent().location(uri).build()) .orElse(ResponseEntity.badRequest().body("Unable to update " + employeeToUpdate)); }