ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring boot] Common Response
    프로젝트/아카이뷰 2024. 1. 9. 21:52

    Common Response 왜 궁금했을까❓

    - SSAFY 1학기 프로젝트에서 시간에 쫒겨 개발을 하다보니 기능 완성에만 집중하여 코드를 작성했다.
    - 그 결과, 일관되지 못한 REST API Response를 받아오게 되고 Client 입장에서 혼란을 야기할 것이라 생각되었다.
    - 이러한 문제점을 Common Response를 만들어 구조화 한다면 Client는 일관된 응답을 통해 일의 생산성과 안정성 측면이 향상될 것이라 생각되어 학습하고 Refactoring을 진행해보려 한다.

     

     

    Common Response

    • 이번 포스팅에서는 Success Response만 다루고 Error Response는 추후 포스팅에서 다루도록 하겠다.
    • 우선, Common Response를 만들기 위해서 응답 구조를 어떻게 구성할지 고민해보았다. 
    • Client의 요청에 대한 데이터를 담기 위한 필드, 서버에서 어떠한 작업이 이뤄졌는지에 대한 설명이 담긴 필드, 응답에 대한 고유 코드가 담길 필드 이렇게 3가지를 구상했다.
    @PutMapping
    public ResponseEntity<Map<String, Object>> ModifyUser(@RequestBody UserDto dto) {
    	Map<String, Object> map = new HashMap<>();
    	try {
    		boolean res = service.modifyUser(dto);
    		map.put("resdata", res);
    		map.put("resmsg", "수정성공");
    
    	} catch (Exception e) {
    		map.put("resmsg", "수정실패");
    		map.put("resdata", e.getMessage());
    	}
    	ResponseEntity<Map<String, Object>> res = new ResponseEntity<>(map, HttpStatus.OK);
    	return res;
    }
    • 위 코드는 Refactoring을 하기 전에 코드로 map Collection을 이용하여 응답 구조를 구성했다.
    • 이러한 코드의 문제점은 일관되지 못한 응답을 야기할 수 있다.
    public class SuccessResponse<T> {
        private final String code;
        private final String message;
    
        @JsonInclude(JsonInclude.Include.NON_EMPTY)
        private final T data;
        
    	...    
    }
    • 위의 문제점을 해결하기 위해 SuccessResponse 클래스를 만들어 CommonResponse 구조를 구성했다.
    public enum SuccessCode implements ResponseCode {
        LOGIN_SUCCESS(HttpStatus.OK, "로그인에 성공했습니다."),
        CREATED_USER(HttpStatus.CREATED, "유저 정보를 생성했습니다."),
        MODIFY_USER_SUCCESS(HttpStatus.OK, "유저 정보를 수정했습니다."),
        ;
        private final HttpStatus httpStatus;
        private final String message;
    }
    • 유지 보수를 쉽게 하기 위해 enum으로 SuccessCode를 구성하였다.
    public static <T> ResponseEntity<Object> createSuccess(final SuccessCode successCode, final T data) {
            return ResponseEntity.status(successCode.getHttpStatus())
                .body(SuccessResponse.builder()
                       .code(successCode.name())
                       .message(successCode.getMessage())
                       .data(data)
                       .build()
                );
    }
    
    public static <T> ResponseEntity<Object> createSuccess(final SuccessCode successCode) {
        return ResponseEntity.status(successCode.getHttpStatus())
                .body(SuccessResponse.builder()
                        .code(successCode.name())
                        .message(successCode.getMessage())
                        .build()
                );
    }
    • SuccessCode를 받아 ResponseEntity를 생성하기 위해 createSuccess Method 2개를 만들었다.
    • 데이터가 존재하는 응답도 있고 없는 응답도 있기 때문에 오버로딩을 하였다.
    @PutMapping
    public ResponseEntity<Object> ModifyUser(@RequestBody UserDto dto) {
    	service.modifyUser(dto);
    	return SuccessResponse.createSuccess(SuccessCode.MODIFY_USER_SUCCESS);
    }
    • Controller에서 다음과 같이 수정하여 코드의 가독성과 일관된 응답을 만들 수 있었다.

     

    '프로젝트 > 아카이뷰' 카테고리의 다른 글

    [Spring boot] JPA(Java Persistence API)  (0) 2024.01.13
    [Spring boot] Error Handling  (1) 2024.01.10
    [Spring boot] WebRTC  (0) 2024.01.08
    [Spring boot] @Builder 어노테이션  (0) 2024.01.05
    [Spring boot] @JsonInclude 어노테이션  (0) 2024.01.04
Designed by Tistory.