在 Rest API 中找不到处理资源

Bre*_*min 6 java spring spring-boot

我正在 Spring Boot 中开发一个 Rest API。当未找到资源实例时,以下哪项是处理的最佳方法?

    @GetMapping(value="/book/{id}")
    public ResponseEntity<Book> getBook(@PathVariable String id){

        Book book = bookService.getBook();

        // Which is best Approach for resource instance not found ?
        if(book == null) {
            // This one
            return new ResponseEntity<>(book, HttpStatus.NO_CONTENT);
            //OR
            return  new ResponseEntity<>(book, HttpStatus.NOT_FOUND);
            //OR 
            throw new DataNotFoundException("Book with id " + id + " Does not exist");
        }

        return new ResponseEntity<>(book , HttpStatus.OK);
    }
Run Code Online (Sandbox Code Playgroud)

我很清楚,当在 Db 中找不到资源集合时,传递一个空集合而不是 null,但我不清楚如何处理资源实例。

我还阅读了 StackOverflow 上的内容,HttpStatus.NOT_FOUND当条件下的资源不能存在而不是在 Db 中不存在时,应该使用它。

处理这个问题的最佳方法是什么?

g00*_*00b 7

使用 Spring MVC 时,返回结果时通常有两种选择,要么使用普通对象,要么使用ResponseEntity类。这两者都不比另一个好。此外,您可以决定是否使用异常来分离错误处理。

鉴于此,您抛出异常的第三种情况与您的前两个选项之一基本相同。默认情况下,抛出异常会导致 500 Internal Server Error,但可以通过使用@ResponseStatus注解来更改,例如:

 @ResponseStatus(HttpStatus.NOT_FOUND) // Or @ResponseStatus(HttpStatus.NO_CONTENT)
 public class DataNotFoundException extends RuntimeException {

 }
Run Code Online (Sandbox Code Playgroud)

或者,您也可以定义异常处理程序。同样,这可以通过使用普通对象或ResponseEntity,例如:

@ResponseStatus(HttpStatus.NOT_FOUND) // Or @ResponseStatus(HttpStatus.NO_CONTENT)
@ExceptionHandler(DataNotFoundException.class)
public Book handleNotFound(DataNotFoundException ex) {
    return null;
}
Run Code Online (Sandbox Code Playgroud)

或者:

@ExceptionHandler(DataNotFoundException.class)
public ResponseEntity<Book> handleNotFound(DataNotFoundException ex) {
    return new ResponseEntity<>(null, HttpStatus.NOT_FOUND); // Or HttpStatus.NO_CONTENT
}
Run Code Online (Sandbox Code Playgroud)

同样,两者都不比另一个好,您的选择主要基于个人喜好。但是,您可能应该始终使用一个。


现在,这意味着还有两个选择,要么选择HttpStatus.NOT_FOUND(404) ,要么选择HttpStatus.NO_CONTENT(204)。虽然您可以在技术上使用任一状态,但它们具有不同的含义:

  • 204 = 请求成功,但什么也没有。
  • 404 = 请求不成功,资源不存在

现在,如果您请求/book/123并且没有 ID 为 123 的书,则可以将其视为不存在的资源,因此HttpStatus.NOT_FOUND最有意义。