HTTP ResponseEntity

my_mon·2023년 3월 19일
0
post-thumbnail
post-custom-banner

ResponseEntity란?

ResponseEntity 클래스는 HTTP 응답(Response)을 나타내는 객체로, 반환된 HTTP 상태코드와 헤더, 응답 본문 등을 포함한다.
ResponseEntity는 밑의 사진에서 보이는 것처럼 HttpEntity를 상속받았기 때문이다.

바로 위의 사진은 HTTP 클래스인데, 헤더와 바디를 멤버필드로 포함하고 있다.
즉 ResponseEntity는 HttpEntity 클래스의 멤버필드 headers, body와 자체적으로 갖고 있는 멤버필드 status(상태코드)를 포함하여 HttpStatus, HttpHeaders, HttpBody를 변수로 갖게 된다.

일반적으로 @Controller@RestController, @RequestMapping 메소드를 사용하여 HTTP 요청에 대한 응답을 반환할 때 사용한다.

예를 들어 HTTP 상태코드가 200인 응답을 반환하려면 다음과 같이 ResponseEntity를 사용할 수 있다.

@GetMapping("/hello")
public ResponseEntity<String> hello() {
    String message = "Hello, World!";
    return ResponseEntity.ok(message);
}

위 코드에서 ResponseEntity.ok(message)는 HTTP 상태코드 200과 "Hello, World!" 메세지를 가진 ResponseEntity 객체를 생성하여 반환한다.


또한 예외가 발생한 경우에도 ResponseEntity를 사용하여 예외에 대한 적절한 HTTP 상태코드와 메세지를 반환할 수 있다. 아래 코드를 보자.
@GetMapping("/users/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
    User user = userRepository.findById(id)
        .orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + id));
    return ResponseEntity.ok(user);
}

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

위 코드는 ReponseEntity를 사용하여 404 Not Found 에러를 반환하는 코드다.
맨 처음으로 데이터베이스에서 해당 id값을 가진 사용자 정보를 조회하는 메소드가 보이는데, 이 때 findById() 메소드는 Spring Data JPA에서 제공하는 메소드중 하나로 결과를 Optional 타입으로 반환 한다.

Optional은 값이 없을 수도 있는 객체를 다룰 때 사용하는 클래스다. 이 타입을 사용하면 null 체크를 하지 않아도 되는 장점이 있다.
Optional.empty() : 조회된 엔티티가 없는 경우 반환되는 객체
orElseThrow() : 예외를 발생시키는 메소드
orElse() : 기본값을 반환하는 메소드

따라서 위 코드에서는 userRepository.findById(id)를 호출하여 조회한 Optional 객체가 값이 없다면, orElseThrow 메소드가 ResourceNotFoundException 예외를 발생시킨다.
즉, "User not found with id: {id}"라는 메세지를 가진 ResourceNotFoundException 예외가 발생하여 HTTP 상태코드 404를 반환한다.

ResourceNotFoundException은 HTTP 요청에 대한 예외처리를 위한 사용자 정의 예외클래스다.
@ResponseStatus(HttpStatus.NOT_FOUND) 어노테이션은 해당 예외가 발생했을 때, HTTP 응답 상태코드를 404 NOT FOUND로 설정해준다. 이는 REST API에서 자주 사용되는 응답 상태코드 중 하나로 클라이언트가 요청한 값이 존재하지 않는 경우에 사용된다.

ResponseEntity Customize

ResponseEntity는 상태코드와 헤더, 바디 중 원하는 것만 선택해서 반환할 수 있다는 큰 장점이 있다.

몇가지 예시를 들어보자

1. 상태코드와 헤더는 그대로 유지, 본문만 변경하고자 할 때

// 원래의 ResponseEntity 객체
ResponseEntity<String> responseEntity = ResponseEntity
    .status(HttpStatus.OK)
    .header("My-Header", "value")
    .body("original body");
  
// 상태 코드와 헤더는 그대로 유지하고, 본문만 변경한 새로운 ResponseEntity 객체
ResponseEntity<String> newResponseEntity = ResponseEntity
    .status(responseEntity.getStatusCode())
    .headers(responseEntity.getHeaders())
    .body("new body");

위의 코드에서, newResponseEntity 객체는 responseEntity 객체와 상태코드와 헤더가 동일하고, 본문만 "new body"로 변경된 새로운 객체가 된다.


2. 바디만 반환하는 경우

@GetMapping("/body")
public ResponseEntity<String> getBody() {
    return ResponseEntity.ok("response body");
}

위 코드에서 ResponseEntity 객체 생성 시, 생성자의 두번째 파라미터로 반환할 바디의 내용을 넘겨주면 된다.

3. 상태코드만 반환하는 경우
게시글의 삭제같은 경우처럼 반환타입이 따로 없는 경우가 있다.
이런 경우에는 상태코드만 반환해줄 수 있는데, 코드는 다음과 같다.

@DeleteMapping("/resources/{id}")
public ResponseEntity<Void> deleteResource(@PathVariable Long id) {
    boolean success = resourceService.deleteResource(id);
    if (success) {
        return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
    } else {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
    }
}

위 코드는 게시글이 무사히 삭제된 경우와, 그렇지 않을 경우에 각각 다른 상태코드를 반환한다.
만약 삭제가 성공했다면 HttpStatus.NO_CONTENT 상태코드와 빈 바디를 가진 ResponseEntity를 반환한다.
반면 삭제에 실패했다면 HttpStatus.NOT_FOUND 상태코드와 함께 빈 바디를 가진 ResponseEntity를 반환한다.

ResponseEntity Methods

ResponseEntity의 메소드들은 서버에서 생성된 HTTP 응답을 생성하기 위한 다양한 방법을 제공해준다. 그 중 자주 사용되는 몇가지 메소드들을 살펴보자

ok() : HTTP 상태코드 200를 반환
notFound() : HTTP 상태코드 404를 반환
getBody() : HTTP 응답 바디에 대한 내용을 반환
getHeaders() : HTTP 응답 헤더에 대한 내용을 반환
getStatusCode() : HTTP 응답 상태코드를 반환한다. 200은 "OK", 404는 "Created", 404는 "Not Found" 등의 의미를 갖고 있다.`

profile
기록하는 사람
post-custom-banner

0개의 댓글