본문 바로가기
컴퓨터 프로그래밍/Spring

[Spring] ApiResponse 예시 코드 분석

by 한33 2024. 9. 21.

package com.sparta.sweethoney.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter
@RequiredArgsConstructor
public class ApiResponse<T> {

    private enum Status {
        SUCCESS, FAIL, ERROR
    }

    private final Status status;
    private final T data;
    private final String message;

    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<>(Status.SUCCESS, data, "요청이 성공적으로 처리되었습니다");
    }

    public static ApiResponse<?> successWithNoContent() {
        return new ApiResponse<>(Status.SUCCESS, null, "요청이 성공적으로 처리되었지만 내용이 없습니다");
    }

    public static ApiResponse<?> fail(BindingResult bindingResult) {
        Map<String, String> errors = new HashMap<>();

        List<ObjectError> allErrors = bindingResult.getAllErrors();
        for (ObjectError error : allErrors) {
            if (error instanceof FieldError) {
                errors.put(((FieldError) error).getField(), error.getDefaultMessage());
            } else {
                errors.put(error.getObjectName(), error.getDefaultMessage());
            }
        }
        return new ApiResponse<>(Status.FAIL, errors, "검증에 실패했습니다");
    }

    public static ApiResponse<?> fail(Map<String, String> errors) {
        return new ApiResponse<>(Status.FAIL, errors, "검증에 실패했습니다");
    }

    public static ApiResponse<?> error(String message) {
        return new ApiResponse<>(Status.ERROR, null, message);
    }
}

private enum Status {
    SUCCESS, FAIL, ERROR
}

 

Status 에 넣을 enum 들을 만들어줬다.


private final Status status;
private final T data;
private final String message;

public static <T> ApiResponse<T> success(T data) {
    return new ApiResponse<>(Status.SUCCESS, data, "요청이 성공적으로 처리되었습니다");
}

public static ApiResponse<?> successWithNoContent() {
    return new ApiResponse<>(Status.SUCCESS, null, "요청이 성공적으로 처리되었지만 내용이 없습니다");
}

 

반환할 필드를  status, data, message 로 해놓고

success 일 때 메세지는 요청이 성공적으로 처리되었다고 반환하고,

만약 void 반환이어서 data 안에 들어가는 데이터가 없을 시에는 successWithNocontent 를 이용할 수 있도록 하였다.


public static ApiResponse<?> fail(BindingResult bindingResult) {
    Map<String, String> errors = new HashMap<>();

    List<ObjectError> allErrors = bindingResult.getAllErrors();
    for (ObjectError error : allErrors) {
        if (error instanceof FieldError) {
            errors.put(((FieldError) error).getField(), error.getDefaultMessage());
        } else {
            errors.put(error.getObjectName(), error.getDefaultMessage());
        }
    }
    return new ApiResponse<>(Status.FAIL, errors, "검증에 실패했습니다");
}

 

@Validated 가 붙어서 쌓인 에러 문구들을 BlindingResult 를 통해서 출력시켜 확인할 수 있다.

 

실제로 사용할 때는 

 

@PostMapping("/signup")
public ResponseEntity<ApiResponse<?>> signup(@RequestBody UserRequestDto userRequest, HttpServletResponse res, BindingResult bindingResult) {
    try {
        return ResponseEntity.ok(ApiResponse.success(userService.signup(userRequest,res)));
    }catch (Exception e){
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(ApiResponse.fail(bindingResult));
    }
}

 

이렇게 메서드 안에 넣어서 사용 가능.