고딩왕 코범석

ResponseEntity란? 본문

Language & Framework/Spring

ResponseEntity란?

고딩왕 코범석 2021. 2. 8. 19:51
반응형

안녕하세요! 오늘은 제가 "스프링과 JPA 기반 웹 애플리케이션 개발"을 클론코딩하면서 보았던 ResponseEntity에 대해 배우고 정리해볼까 합니다. 우선, 저는 RestController에서 도메인 객체를 DTO로 변환해서 반환했습니다.


하지만 단순히 값만 보내는 것이 아닌 헤더, 바디, 상태 코드도 같이 보내줘야 하는 세심함도 알아야 진짜 백엔드 개발자 나는 가짜개발자! 악! 라고 생각하여 이번 기회에 공부하게 되었습니다. 부정확한 정보가 있을 경우에는 항상 댓글을 부탁드리겠습니다. 그럼 시작할게요! 참고로 저는 이 포스팅을 참조해서 작성했습니다.


ResponseEntity?

Spring에서 제공하는 클래스 중 HttpEntity라는 클래스가 존재합니다. 이것은 HTTP 요청 또는 응답에 해당하는 Header, Body를 포함하는 클래스입니다. 구조를 보시죠.

public class HttpEntity<T>{
    private final HttpHeaders headers;
    private final T body;
}

그리고 제가 살펴본 ResponseEntity의 구조는 다음과 같습니다.

public class ResponseEntity<T> extends HttpEntity<T> {
    private final Object status;
}

ResponseEntity는 상속받은 HttpEntity의 헤더와 바디, 해당 클래스에서 상태를 가지고 있습니다.


생성자를 보시게 되면

public ResponseEntity(HttpStatus status) {
    this(null, null, status);
}
public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatus status {
    this(body, headers, (Object) status);
}

요렇게 구조가 되어있습니다. 몇개가 더 있는데, 바디부분과 헤더부분은 null이 들어올 수 있습니다. 결국 this를 통해 세 개의 매개변수가 있는 생성자를 호출한다는 뜻입니다.

사용하기

이제 사용해보겠습니다. DTO를 하나 만들어 보겠습니다.

package com.example.demo.responseEntityExample;

import lombok.Data;

@Data
public class MyDto {
    private StatusEnum status;
    private String message;
    private Object data;

    public MyDto() {
        this.status = StatusEnum.BAD_REQUEST;
        this.data = null;
        this.message = null;
    }
}

상당히 귀여운 dto입니다. 다음은 필드에 선언한 enum타입의 StatusEnum입니다.

package com.example.demo.responseEntityExample;

public enum StatusEnum {
    OK(200, "OK"),
    BAD_REQUEST(400, "BAD REQUEST"),
    NOT_FOUND(404, "NOT FOUND"),
    INTERNAL_SERVER_ERROR(500, "INTERNAL SERVER ERROR");

    int code;
    String message;

    StatusEnum(int code, String message) {
        this.code = code;
        this.message = message;
    }
}

다음은 제가 설정한 User 도메인입니다. 단순함을 위해 jpa쪽 설정은 따로 건드리지 않았습니다.

package com.example.demo.responseEntityExample;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {

    private Long id;
    private String name;
    private String city;

}

이제 컨트롤러를 보겠습니다.

package com.example.demo.responseEntityExample;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.Charset;

@RestController
@RequiredArgsConstructor
public class ResponseEntityController {

    private final ResponseEntityService service;

    @GetMapping("/user/{id}")
    public ResponseEntity<MyDto> findByid(@PathVariable Long id) {
        User user = service.getUser();
        MyDto dto = new MyDto();

        HttpHeaders header = new HttpHeaders();
        header.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));

        dto.setStatus(StatusEnum.OK);
        dto.setData(user);
        dto.setMessage("고범석 찾기 성공");

        return new ResponseEntity<>(dto, header, HttpStatus.OK);
    }
}

서비스에서는 그냥 단순히 User를 생성해서 가져왔습니다. get메서드의 반환 타입을 ResponseEntity<>로 설정했고, 앞에서 설명드렸던 dto의 타입이 T body 변수의 지네릭 타입으로 갑니다.


HttpStatus

org.springframework.http 에 위치했습니다. 얘도 Enum타입이며 모든 상태들과 메세지들이 여기 있습니다.

HttpHeaders

헤더의 contentType을 json으로 설정해주었습니다.


이제 결과는 어떻게 나왔을까요?

image

제가 원하는대로 잘 나왔습니다. 친구들은 다 직장다녀서 저라도 절 찾아야지 누가 날 찾겠습니까...

요러한 방식으로 프론트엔드 개발자님들과 협업을 하는 것 같습니다?? 앞으로 ResponseEntity를 활용해서 반환하는 방식을 애용해서 좀 더 깔끔하게 클라이언트로 반환해줄 수 있는 연습을 프로젝트에서도 해봐야겠다.

반응형