Что вернуть, если элемент отсутствует?

#spring #spring-boot

#spring #весна-загрузка

Вопрос:

Учитывая этот код:

 @GetMapping("/data/{id}")
public Data retrieveDataById(@PathVariable Long id) {

    Optional<Data> data = dataService.findById(id);

    if(data.isEmpty()){
        return null;
    }
    else {
        return data.get();
    }

}
  

Основная проблема, я думаю, заключается в том, что null возвращается, если элемент не найден.

Итак, вместо

     if(data.isEmpty()){
        return null;
    }
  

Я планирую изменить его на:

     if(data.isEmpty()){
        ResponseEntity.ok("No records found for id" id);
    }
  

Это правильно или есть другие изменения, которые я должен рассмотреть?

Обновить:

Изменение приводит к изменению возвращаемого типа с Data на ResponseEntity . Должен ли я добавить data.get(); в ResponseEntity , если данные присутствуют? Изменение

Комментарии:

1. Использовать ResponseEntity — это нормально. Просто подумайте о коде состояния http

2. Не занимаясь весной в течение длительного времени, но new ResponseEntity<String>("", HttpStatus.NOT_FOUND) или ResponseEntity.notFound().build() было бы лучше

Ответ №1:

Было бы лучше обернуть ответ при возврате с контроллеров

 @GetMapping("/{id}")
    public ResponseEntity<RoleDto> findById(@PathVariable String id) {
        return ResponseEntity.ok(roleService.findById(id));
    }
  

Для уровня обслуживания возврат пользовательского исключения с соответствующим сообщением об ошибке был бы более гибким при рассмотрении ситуации позже.

 public RoleDto findById(String id) {
        Optional<Role> role = roleRepository.findById(id);
        return role.map(roleMapper::toDto).orElseThrow(() -> new ResourceNotFoundException(id, "Role not found"));
    }
  

Пользовательское исключение может быть обработано в соответствии с требованиями конечного пользователя путем реализации @ControllerAdvice, уровня контроллера @ExceptionHandler или ResponseStatusException из Spring 5

Изменение приводит к изменению типа возвращаемого значения с Data на ResponseEntity. Должен ли я добавить data.get(); в ResponseEntity, если данные присутствуют? Изменение

Да, вы можете. Обычно вы можете выполнить эту операцию на уровне сервиса и вернуть DTO соответствующему контроллеру.

Ответ №2:

Необязательно дает вам возможность выполнять некоторые операции с его значением потоковым способом. Если вы разрабатываете конечные точки rest весной, вы могли бы либо вернуть ResponseEntity, как упоминал Joop Eggen, либо вы могли бы создать @ControllerAdivce и создать исключение, которое оно перехватило бы и отправило надлежащий статус http. С точки зрения масштабируемости, второй подход лучше, потому что вы можете использовать его с различными контроллерами.

Итак, первый случай:

 @GetMapping("/data/{id}")
public ResponseEntityy<?> retrieveDataById(@PathVariable Long id) {
    return dataService.findById(id)
             .map(value -> new ResponseEntity<>(value, HttpStatus.OK))
             .orElse(ResponseEntity.notFound().build());
}
  

Второй случай:

 @GetMapping("/data/{id}")
public Data retrieveDataById(@PathVariable Long id) {
    return dataService.findById(id).orElseThrow(() -> new YourCustomRuntimeException());
}

@ControllerAdvice
class ControllerExceptionHandler {
    @ResponseStatus(HttpStatus.NOT_FOUND) 
    @ExceptionHandler(YourCustomRuntimeException.class)
    public ResponseEntity elementNotFound() {
        return ResponseEntity.notFound().build();
    }
}
  

Ответ №3:

если вы не хотите использовать ResponseEntity, вы также можете создать исключение ResponseStatusException, как показано здесь:https://www.baeldung.com/spring-response-status-exception#1-generate-responsestatusexception

Ответ №4:

Вы могли бы изменить его на like :

 @GetMapping("/data/{id}")
public Data retrieveDataById(@PathVariable Long id) {

    Optional<Data> data = dataService.findById(id);

    if(data.isEmpty()){
        return new ResponseEntity("No records found for id" id , HttpStatus.NOT_FOUND);
    }
    else {
        return data.get();
    }

}
  

Измените HttpStatus код на 404, который указывает NOT FOUND вместо возврата 200 в качестве кода состояния для этого сценария.