스프링부트 Response 만들기

Jemin·2023년 10월 25일
0

백엔드

목록 보기
19/21
post-thumbnail

간단한 토이 프로젝트 진행 중에 API Response를 만들어주다가 공통으로 만들면 편하지 않을까 해서 이것저것 찾아보다가 신기한게 많아서 공부한 내용을 정리해보려 한다.

ResponseEntity

일반적으로 클라이언트에서 서버로 요청을 보내면 서버에서 처리한 후 응답을 클라이언트로 다시 보내주어야 한다.

이 경우 String으로 보내는 것이 아니라 ResponseEntity를 사용해서 응답값을 생성해 반환하는 것이 일반적인 방법이라고 한다.

ResponseEntity는 스프링 프레임워크에서 제공하는 클래스로, HTTP 응답을 나타내는 객체다. 이 클래스는 웹 애플리케이션에서 컨트롤러 메서드에서 생성된 응답 데이터를 래핑하고, HTTP 응답 헤더 및 상태 코드를 설정할 수 있는 방법을 제공한다.

특징과 용도

  • HTTP 응답 데이터 래핑: HTTP 응답으로 반환할 데이터를 포함한다. 이 데이터는 JSON, HTML, XML 또는 기타 형식일 수 있으며, 제네릭 타입을 사용하여 지정할 수 있다. 예를 들어, ResponseEntity<String>은 문자열 데이터를 나타낸다.

  • HTTP 헤더 설정: HTTP 응답 헤더를 설정할 수 있다. HTTPHeaders를 사용하여 커스텀 헤더를 추가하거나 Content-Type, Content-Disposition 등의 기본 헤더를 설정할 수 있다.

  • HTTP 상태 코드 지정: HTTP 응답의 상태 코드를 설정하는데 사용된다. 예를 들어 ResponseEntity.ok()는 HTTP 상태 코드 200 (OK)을 설정한다.

  • 유연성: 스프링 컨트롤러에서 ResponseEntity를 반환하면, HTTP 응답의 상태 코드, 헤더 및 본문 데이터를 동적으로 조작할 수 있다. 이것은 다양한 상황에 따라 다른 응답을 생성하고 반환하는데 사용된다.

  • Exception Handling: 예외 처리에 활용할 수 있다. 예외가 발생한 경우, 컨트롤러 메서드에서 responseEntity를 사용하여 에러 응답을 반환할 수 있다.

간단한 예제

@GetMapping("/example")
public ResponseEntity<String> example() {
    String data = "Hello, World!";
    HttpHeaders headers = new HttpHeaders();
    headers.add("Custom-Header", "SomeValue");
    return new ResponseEntity<>(data, headers, HttpStatus.OK);
}

/example 엔드포인트에 대한 GET 요청에 응답하는 컨트롤러다. ResponseEntity를 사용하여 응답 데이터, 헤더 및 HTTP 상태 코드가 설정된다.

공통 Response 만들기

하나하나 모든 ResponseEntity를 만들기에는 중복되는 코드도 많고 프론트개발을 주로 하다보니 공통 Response를 찾아서 만들어보게 되었다.

응답을 JSON 객체로 보내기 위해 먼저 ResponseData를 만들어주었다.

package com.toy.web.response;

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

@Data
@AllArgsConstructor // 생성자를 자동으로 만들어 준다
public class ResponseData<T> {
    private int statusCode;
    private String responseMessage;
}

여기까지는 괜찮았다. statusCode와 responseMessage는 생성자를 통해 할당해주면 된다.

하지만 반환하는 data가 있는 응답도 있고 없는 응답도 있을 것이다. 이 경우에 어떻게 해야하는지 살펴보자.

StatusCode

먼저 공통 HTTP 응답을 만들어 주었다.

package com.toy.web.response;

public class StatusCode {
    public static final int OK = 200;
    public static final int CREATED = 201;
    public static final int BAD_REQUEST = 400;
    public static final int NOT_FOUND = 404;
    public static final int INTERNAL_SERVER_ERROR = 500;
}

아직 배우는 단계이기 때문에 그렇게 많지 않고 간단하게 몇 개만 작성했다.

ResponseMessage

package com.toy.web.response;

public class ResponseMessage {
    public static final String SIGN_IN_SUCCESS = "로그인 성공.";
    public static final String SIGN_IN_FAIL = "로그인 실패.";
    public static final String SIGN_UP_SUCCESS = "회원가입 성공.";
    public static final String SIGN_UP_FAIL = "회원가입 실패.";
    public static final String ALREADY_USER = "이미 존재하는 아이디입니다.";
}

아직 로그인, 회원가입 기능을 만드는 중이라 이번에도 필요한 것만 먼저 작성했다.

Builder

참고한 글에서 처음보는 패턴을 사용해서 만들길래 일단 따라 만들고 한줄 한줄 뜯어봐서 이해했다.

package com.toy.web.response;

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

@Data
@AllArgsConstructor // 생성자를 자동으로 만들어 준다
@Builder
public class ResponseData<T> {
    private int statusCode;
    private String responseMessage;
    private T data;

    public ResponseData(final int statusCode, final String responseMessage) {
        this.statusCode = statusCode;
        this.responseMessage = responseMessage;
        this.data = null;
    }

    public static<T> ResponseData<T> res(final int statusCode, final String responseMessage) {
        return res(statusCode, responseMessage, null);
    }

    public static<T> ResponseData<T> res(final int statusCode, final String responseMessage, final T t) {
        return ResponseData.<T>builder()
                .data(t)
                .statusCode(statusCode)
                .responseMessage(responseMessage)
                .build();
    }
}
  • Lombok@Builder 어노테이션: 이 어노테이션을 사용하면 객체를 더 쉽게 생성할 수 있다. ResponseData 클래스에 빌더 패턴을 생성하고, 메서드 체이닝을 통해 객체를 초기화할 수 있다.

  • private T data;: 응답 데이터를 저장하고 아직 타입이 정해지지 않은 제네릭 타입의 필드다.

빌더 패턴
빌더 패턴은 복잡한 객체의 생성을 단순화하고 가독성을 향상시키기 위한 디자인 패턴 중 하나다.
객체를 구성하는 단계에서 메서드 체이닝을 통해 표현할 수 있다.
선택적인 필드만 설정하고, 나머지는 기본값으로 초기화할 수 있다.
객체의 불변성을 유지할 수 있다. 객체가 생성된 후에 필드를 변경할 수 없다.

이와 같이 빌더 패턴으로 코드를 작성하면 컨트롤러에서 사용할 때 아래와 같이 사용할 수 있다.

ResponseEntity(ResponseData.res(StatusCode.OK, ResponseMessage.SIGN_IN_SUCCESS), HttpStatus.OK);

만약 보내줄 데이터가 없다면 파라미터가 2개인 생성자를 통해서 data를 null로 초기화 해준다.

참고
[Spring Boot] 클라이언트 REST API 응답보내기

profile
경험은 일어난 무엇이 아니라, 그 일어난 일로 무엇을 하느냐이다.

0개의 댓글