[ Spring ] ResponseEntity

5tr1ker·2023년 4월 7일
0

Spring

목록 보기
1/10
post-thumbnail

서론

Spring 에서 HTTP Response 를 만드는 것이 중요하며, 응답의 상태 코드뿐만 아니라 , Body에 들어갈 내용도 포함해 반환해주어야합니다. 이 세가지 요소 ( 응답 코드 , 내용 , 헤더 ) 를 가진 객체를 구성해 주는것이 @ResponseBody 와 ResponseEntity 입니다.

@ResponseBody

HTTP 규격에 맞는 응답으로 만들어 주는 어노테이션으로 HTTP의 요청을 객체로 변환하거나 , 객체를 응답으로 변환하는 HttpMessageConverter 를 사용합니다.

Annotation 을 추가하여 간단하게 처리할 수 있는 장점이 있지만, HTTP Header 를 유연하게 설정할 수 없다는 단점이 있습니다. 이러한 부분을 해결하기 위해 ResponseEntity를 사용합니다.

@ResponseBody 만 사용하면 뷰를 제공하지 않고 데이터만 전송하기 때문입니다.

ResponseEntity란?

ResponseEntity는 HttpEntity 를 상속받아 , 응답 데이터와 HTTP 상태 코드를 직접 제어할 수 있는 클래스입니다. HttpEntity를 상속 받았기 때문에 HttpMessageConverter 를 사용할 수 있어 이를 통해 Json으로 응답합니다.

또한 HTTP 아키텍처 형태에 맞게 Response 를 보내주는 역할도 합니다.

따라서 ResponseEntity 클래스를 사용하면 결과값과 상태코드 , 헤더값을 모두 포함하여 응답할 수 있습니다.

ResponseEntity는 HTTP 상태 코드와 응답 데이터를 함께 전송할 수 있기 때문에 세밀한 제어가 필요한 경우에 사용합니다.

HttpEntity

Http 요청 또는 응답에 해당하는 HttpHeader와 HttpBody를 포함하는 클래스입니다.

public class HttpEntity<T> {

	private final HttpHeaders headers;

	@Nullable
	private final T body;
}

HttpEntity 클래스를 상속받아 구현한 클래스가 ResponseEntity , RequestEntity 클래스이며 HttpRequest에 대한 응답 데이터를 사용하고 있습니다.

ResponseEntity 의 구조

ResponseEntity 는 HttpEntity를 상속받고 사용자의 HttpRequest에 대한 응답 데이터가 포함된 클래스이기 때문에 HttpStatus , HttpHeaders , HttpBody 를 포함합니다.

구현된 인터페이스를 보면 순서대로 바디 , 헤더 , 상태코드 순으로 생성자가 만들어집니다.

HTTP Header 에는 요청이나 응답에 대한 요구사항이 들어있고 , HTTP Body 에는 그 내용이 들어있습니다.

Response Header form

요청한 메세지에 대해 성공했는지에 대한 여부와 요청한 응답 값들이 body 에 담겨옵니다.

  • Location : 3xx 상태 코드일 때 볼수있는 헤더로 서버의 응답에 대한 URI 를 알려줍니다. ( 서버의 응답이 다른곳에 있다고 알려줍니다. )
  • Server : 웹 서버의 종류 ex ) Nginx
  • Age : max-age 시간 내에 얼마만큼 시간이 흘렀는지 초 단위로 알려줍니다.
  • Referrer-policy : 서버 referrer 정책을 알려주는 값 ( origin , no-referrer , unsafe-url )
  • WWW-Authenticate : 사용자 인증이 필요한 자원을 요구할 때 , 서버가 제공하는 인증 방식
  • Proxy-Authenticate : 요청한 서버가 프록시 서버인 경우 유저 인증을 위한 값

ResponseEntity 사용 예시

ResponseEntity 클래스 내부를 보게 되면 다양한 생성자가 존재하여 우리는 필요한 값만 대입하면 나머지 값은 null 로 채워서 응답을 합니다.

  • 작성 예시 1 : 상태 코드만 반환할 때
@PostMapping("/post/like")
public ResponseEntity<Objects> updateLike(@RequestBody SetLikeDto.Request postLikeDto, @AuthenticationPrincipal UserDetailsImpl userDetails){
    Post post = postService.setPostLike(postLikeDto,userDetails.getUser());

    SetLikeDto.Response response = modelMapper.map(post, SetLikeDto.Response.class);

	// builder 사용하기
    return ResponseEntity.ok().build();
    // 생성자를 사용하기
    return new ResponseEntity(HttpStatus.OK);
}
  • 작성 예시 2 : 상태 코드만 반환할 때
@PostMapping("/post/like")
public ResponseEntity<Objects> updateLike(@RequestBody SetLikeDto.Request postLikeDto, @AuthenticationPrincipal UserDetailsImpl userDetails){
    Post post = postService.setPostLike(postLikeDto,userDetails.getUser());

    SetLikeDto.Response response = modelMapper.map(post, SetLikeDto.Response.class);

	// builder 사용하기
    return ResponseEntity.ok(response);
    // 생성자를 사용하기
    return new ResponseEntity<>(message, headers , HttpStatus.OK);
}

데이터 타입의 형식을 맞춰주기 위해 와일드 카드 <?> 를 사용하기 보다 Objects 타입으로 명시해 주는것이 가독성 측면과 , 오류 발생 가능성 , 유지보수 측면에서 좋습니다.

또한 ResponseEntity를 사용할 때 Constructor를 사용하기 보다 Builder 를 사용하는 것을 권장하고 있습니다. ( 잘못된 상태 코드를 넣을 수 있기 때문입니다. )

참고

참고 블로그 1 : https://thalals.tistory.com/268
참고 블로그 2 : https://wonsjung.tistory.com/448
참고 블로그 3 : https://sudo-minz.tistory.com/m/134#:~:text=ResponseEntity%EB%8A%94%20%EC%82%AC%EC%9A%A9%EC%9E%90%EC%9D%98%20HttpRequest,HttpHeaders%2C%20HttpBody%EB%A5%BC%20%ED%8F%AC%ED%95%A8%ED%95%9C%EB%8B%A4.

profile
https://github.com/5tr1ker

0개의 댓글