본문 바로가기
Back-end/개발 기록

Spring 프로젝트 API 공통 response 처리 과정 개발 기록

by kkkdh 2023. 9. 13.
728x90

들어가며...

개발하는 서버가 요청에 대한 응답으로 바로 view를 브라우저로 전달하는 경우에는 다음과 같이 thymeleaf 같은 템플릿 엔진을 이용해 view를 전달하면 그만입니다.

하지만, HTTP API(REST API)를 개발하는 경우 규격에 맞는 응답 처리를 구현해야 한다는 것을 짧은 실무 개발 경험으로 배우게 되었습니다.

 

오늘은 사이드 프로젝트에서 API 개발 과정에서 response 처리의 일부 과정을 공통으로 처리하도록 개발하는 과정을 정리해 볼까 합니다.

 


HttpEntity, ResponseEntity를 이용하는 방식과 그렇지 않을 때의 차이점

@RestController 어노테이션을 이용해 controller를 구현하는 경우 @Controller + @ResponseBody 조합을 이용하는 것과 같습니다.

 

이때, @ResponseBody 어노테이션을 이용해서 응답을 처리하는 경우 Spring MVC에 의해 HttpMessageConverter interface를 거치게 되고, 알맞은 HttpMessageConverter 구현체이용해 객체를 json 형태의 데이터로 변환하는 것입니다.

이런 식으로 제공되는 정적 메서드를 이용해 status code 지정 가능 (ok: 200)

이 과정에서 ResponseEntity 혹은 HttpEntity를 사용하면, HTTP status code를 설정한 response 반환이 가능합니다.

 

 @PostMapping // Generic wildcard ? 사용 (모든 타입 허용)
public CommonResponseDto<?> savePost(PostCreateRequestDto requestDto){
    PostCreateResponse response = postService.save(requestDto);

    // HTTP status code: 200 고정
    return CommonResponseDto.builder()
                .success(true)
                .response(response)
                .build();
}

물론 위와 같이 ResponseEntity로 감싸지 않고, 객체를 반환해도 HttpMessageConverter에 의해 json 형식으로 반환이 가능하지만, status code는 200 고정이라는 점을 유념해야 합니다.

 

 

따라서 필요한 경우 ResponseEntity를 이용해 알맞은 status code를 지정한 뒤 반환하고, 일반적인 경우 200을 사용하기 때문에, 객체를 그대로 반환하는 식으로 처리해도 괜찮을 것 같습니다.

 

 


Response를 처리할 때 사용하는 공통 클래스 개발과 그 이유

@Getter
@RequiredArgsConstructor
public class PostCreateResponse {
    private final Long id;
    private final String title;
    private final String content;
    private final String password;
    private final Long viewCount;
}

예를 들어 위와 같은 DTO를 그대로 반환해서 response로 전달한다고 가정하면, 이에 따른 json 응답은 다음과 같을 것입니다.

json 응답 예시

물론 이렇게 처리를 해도 API 마다 하나하나 설명만 잘 한다면, 협업 상황에서 문제가 없을 수도 있겠지만, 만약 에러 상황에서는 다음과 같은 json을 전달한다고 해보죠?

그저 예시일 뿐..

이렇게 일관성 없게 API 응답을 전달하는 경우 모든 API에 대해서 하나하나 자세히 소통하며, key에 따른 value 유형을 약속하는 과정도 매우 지옥 같을 것입니다..

 

당연히 알아서 잘 전달해주는 방식이 협업에서 훨씬 유리하겠죠??

 

그래서 저는 위와 같은 규격에 따라서 API에 대한 응답이 전달되도록 설계한뒤, 사이드 프로젝트의 API 개발을 이어가기로 했습니다.

 

저 data에 해당하는 부분에 원래 전달하려던 객체의 정보를 전달하면, 서버에 요청을 보낸 클라이언트는 success나 message와 같은 정보를 통해 data가 온전하게 전달이 되었는지 등의 정보를 파악하기 훨씬 수월할 것입니다.

 

그래서 이렇게 CommonResponseDto를 만들어 줍니다.

 

Service 단에서 제공하는 Result 객체

그리고 각각의 응답 data로 넣어줄 객체를 위의 예시 처럼 만들어 전달한다면, 통일된 양식으로 API response를 전달할 수 있습니다.

개선된 응답 json 양식

이제 다음과 같은 양식으로 json data 반환이 가능합니다.

 

 

이뿐만 아니라, 정적 메서드 설계를 통해 원하는 응답 코드에 따라 CommonResopnseDto를 ResponseEntity로 감싸서 처리하도록 개발해야 하며, Service 단에서 발생한 RuntimeException에 따른 response 처리 등을 개발해서 위 코드들을 개선할 수 있습니다.

 


참고한 글들

https://velog.io/@qotndus43/%EC%8A%A4%ED%94%84%EB%A7%81-API-%EA%B3%B5%ED%86%B5-%EC%9D%91%EB%8B%B5-%ED%8F%AC%EB%A7%B7-%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B8%B0

 

스프링 API 공통 응답 포맷 개발하기

클라이언트 ↔︎ 서버 구조에서클라이언트는 서버에 요청을 보내고 서버는 요청에 대한 결과를 응답합니다.예를 들어 클라이언트가 1번 상품을 요청하는 경우 서버는 1번 상품을 조회해 응답하

velog.io

https://kkkdh.tistory.com/entry/Spring-MVC-%EA%B8%B0%EB%B3%B8-%EA%B8%B0%EB%8A%A5

 

[Spring MVC] 기본 기능

Logging 이제 System.out.println() method 같은 시스템 콘솔을 사용해서 필요한 정보를 출력하지 않고, 로거를 사용하자. SLF4J SLF4J Simple Logging Facade for Java (SLF4J) The Simple Logging Facade for Java (SLF4J) serves as a si

kkkdh.tistory.com

 

728x90

댓글