본문 바로가기
Spring

[Spring] CustomReponseEntity

by 옹알이옹 2023. 8. 9.

 


 1. CustomResponseEntity이란

API서버를 만들 때 json형태의 어떠한 값들을 리턴한다.
이때 우리는 여러가지의 객체들을 json으로 변환을 하고 추가로 statusCode, 메시지들을 클라이언트에게 전달한다.
이 값들의 어느 정도 공통적인 형태로 규격화 시키기 위하여 만든 것을 CustomReponseEntity라고 명칭하고 있으며, 해당 명칭은 사용자마다 다르고 그 공통적인 형태를 만드는 것도 사람마다 가지각색이라 정답이 없는 거 같다.

 2. 다양한 형태의 API 리턴 값

API서버를 만들다보면 기본적으로 목록,단일 객체,등록,수정,삭제 등을 구현하게 된다. 그것들에 대한 리턴 값은 어떻게 되는지 확인 해보자.

 

2-1. 목록 조회 시 리턴 값

/**
 * 게시판 목록 조회
 *
 * @return
 */
@GetMapping("/board")
public List<BoardDto> selectBoardList(){

    List<BoardDto> boardList = boardService.selectBoardAll();

    return boardList;
}
  • 위의 컨트롤러는 @RestController가 선언이 되어 있어 리턴값을 자동으로 json으로 변환해주는 상황이다.
  • 실제 리턴 값은 아래와 같다.
[
    {
        "boardNo"39,
        "member": {
            "createDt""2023-08-02T00:00:00",
            "updateDt""2023-08-02T00:00:00",
            "memberNo"2,
            "memberId""test2",
            "password""123",
            "email""test2@naver.com",
            "firstNm""t",
            "lastNm""ster2"
        },
        "boardNm""보드3",
        "useAt""Y",
        "comCode"null
    },
    {
        "boardNo"40,
        "member": {
            "createDt""2023-08-02T00:00:00",
            "updateDt""2023-08-02T00:00:00",
            "memberNo"2,
            "memberId""test2",
            "password""123",
            "email""test2@naver.com",
            "firstNm""t",
            "lastNm""ster2"
        },
        "boardNm""보드4",
        "useAt""Y",
        "comCode"null
    }
]
실제 목록 데이터와 status 코드 두 가지를 확인할 수 있다. 만약 FO 개발자가 해당 API 데이터를 가지고 작업을 한다고 한다면 곤란할 것이다. 보통의 경우 리스트의 목록 개수, 검색값등이 필요하기 때문이다.
그렇다면 해당 정보들을 포함 할 수 있는 공통의 객체가 있다면 좋지 않겠는가

 

2-2. 등록,수정,삭제 시 리턴 값

/**
 * 게시판 생성
 *
 * @param boardCreateDto
 * @return
 */
@PostMapping("/board")
@ResponseStatus(HttpStatus.CREATED)
public String createBoard(@Valid @RequestBody BoardCreateDto boardCreateDto){

    boardService.createBoard(boardCreateDto);
    String message = "게시판 생성 성공";
    return message;
}

해당 요청에 대한 응답은 위와 같다.
게시판 조회와 같은 API서버에서 리턴된 값이지만, 해당 요청은 메시지와 status 코드만 확인이 된다.

 

 3. CustomResponseEntity 구성 및 사용법

 

3-1. 구성

위의 상황처럼 같은 서버에서 값을 리턴 해주더라도 요청에 따라 리턴값의 형태가 다르다면, 해당 API서버를
사용하는 클라이언트도 불편할 것이고, API 서버를 개발하는 개발자들 입장에서도 사람마다 응답 객체의 형태가 다를 수 있어 혼란스러울 수 있다.
그러하여 그런것들을 방지하기 위해 하나의 공통 응답 객체를 만들었고, 구성과 사용법은 아래와 같다.

 

CommonResponseEntity => 공통 응답 객체

public class CommonResponseEntity<T> {

    private T data;

    private SearchDto searchDto;

    private String message;

    public CommonResponseEntity(T data, String message) {
        this.data = data;
        this.message = message;
    }

    public CommonResponseEntity(T data,SearchDto searchDto,String message) {
        this.data = data;
        this.searchDto = searchDto;
        this.message = message;
    }
}
Generic 타입은 해당 글을 보면 이해가 되실 겁니다. https://tytydev.tistory.com/27

 

먼저 기본적인 필드는 보는 것과 같이 3가지를 가진다.

  1. private T data => 목록 조회나 상세 조회 시 해당 객체를 담는 필드, 여러 타입이 담겨야 하므로 Generic 타입 사용
  2. private SearchDto searchDto  =>  목록 조회 시 검색값이 있을 경우 해당 값을 담아줌
  3. private String message  => 조회를 제외한 CRD 행위를 했을 시 성공 메세지를 담아줌

 

3-2. 사용법

 

게시판 목록 조회

@GetMapping("/board")
public CommonResponseEntity<List<BoardDto>> selectBoardList(@RequestBody SearchDto searchDto){

    System.err.println("searchDto : "+searchDto);
    PageRequest pageRequest = PageRequest.of(searchDto.getPage(), searchDto.getSize());

    List<BoardDto> boardList = boardService.selectBoardAll(searchDto, pageRequest);

    return new CommonResponseEntity<>(boardList,searchDto,null);
}
  • Board에 대한 목록이므로 Generic타입은 List<BoardDto>로 지정해 준 뒤 순차적으로 목록조회 수, 검색값, 메시지를 넣어주었다.

결과

{
    "data": [],
    "searchDto": {
        "page"1,
        "size"2,
        "searchKeyword""boardNm",
        "searchValue""보드2"
    },
    "message"null
}

 

게시판 생성

@PostMapping("/board")
@ResponseStatus(HttpStatus.CREATED)
public CommonResponseEntity<?> createBoard(@Valid @RequestBody BoardCreateDto boardCreateDto){

    boardService.createBoard(boardCreateDto);
    String message = messageSource.getMessage("success.create",new String[]{"Board"} ,Locale.KOREA);
    return new CommonResponseEntity<>(null,message);
}

조회 데이터는 없으므로 null을 준 뒤, message는 message-properties를 사용하여 코드화 한 뒤 사용하였다.

결과

{
    "data"null,
    "searchDto"null,
    "message""Board 등록(생성) 성공"
}
 
 

결론

API서버에 대한 각 요청에 대해 공통적인 형태의 응답 데이터를 클라이언트에게 제공할 수 있게 되었다.
또한 API 서버에 개발자들 또한 응답 형태에 대한 고민을 하지 않아도 된다.

 

 

 


 

반응형

'Spring' 카테고리의 다른 글

Spring REST API @Valid  (0) 2024.03.06
Spring 비지니스 로직 위치  (0) 2024.02.25
Spring 의존 주입 에러 상황  (0) 2024.02.20
Springboot ftp 파일 업로드/다운로드  (0) 2023.08.25