Ho due percorsi:
-
/students
-
/students/{id}/addresses
... con il seguente comportamento:
POST
in /students
- 201 Created
(se lo studente è stato creato con successo)
POST
in /students/{id}/addresses
- 201 Created
(se è stato creato correttamente l'indirizzo sotto l'utente richiesto)
Ora immagina una situazione in cui il cliente POST
a /students/12/addresses
, ma non c'è Studente con id = 12.
Come devo gestire questo scenario?
Devo inserire senza alcun controllo e attendere che DAO lanci le eccezioni o, prima di inserirmi, dovrei controllare l'esistenza dello studente?
Prima opzione :
StudentController.java
@Autowired
private AddressService addressService;
@PostMapping("/students/{id}/addresses")
public ResponseEntity<?> handleRequestOfCreateAddressToStudent(@PathVariable("id") Long studentId, @RequestBody Address address) {
address.setStudent(new Student(studentId));
Address createdAddress = addressService.saveAddress(address);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").build(createdAddress.getId());
return ResponseEntity.created(location).build();
}
AddressService.java
@Autowired
private AddressRepository addressRepository;
public Address saveAddress(Address address) {
// omitted for brevity...
return addressRepository.save(address);
}
In questo modo, dal momento che sto usando il framework Spring, la riga return addressRepository.save(address);
genererebbe un DataIntegrityViolationException
, perché il vincolo è violato (non c'è Studente con tale ID da legarsi con quell'indirizzo). E, poiché ho bisogno di inviare la risposta al client, dovrei tradurre l'eccezione che viene lanciata.
2nd opzione:
StudentController.java
@Autowired
private StudentService studentService;
@Autowired
private AddressService addressService;
@PostMapping("/students/{id}/addresses")
public ResponseEntity<?> handleRequestOfCreateAddressToStudent(@PathVariable("id") Long studentId, @RequestBody Address address) throws StudentNotFoundException {
Student student = studentService.findById(studentId);
if(student == null)
throw new StudentNotFoundException("message");
address.setStudent(new Student(studentId));
Address createdAddress = addressService.saveAddress(address);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").build(createdAddress.getId());
return ResponseEntity.created(location).build();
}
In questo modo, non ho bisogno di tradurre l'Eccezione, perché so già che lo Studente non esiste così da poter generare un'eccezione personalizzata.
I miei pensieri in entrambi gli approcci:
- Senza controllo, riduco il codice e il numero di volte attiva il mio database;
- Controllo, so esattamente perché non riesco ad aggiungere l'indirizzo (il Lo studente non esiste) e può lanciare un'eccezione personalizzata senza dovendo tradurlo;
Qual è l'approccio migliore per questo scenario?
Devo aspettare che il DAO lanci l'Eccezione, o dovrei impedirgli di lanciare controllando se lo Studente esiste?