[ShareMore] 3. API Response ํ†ต์ผ

1

[ํ† ์ดํ”„๋กœ์ ํŠธ] Share More

๋ชฉ๋ก ๋ณด๊ธฐ
4/6
post-thumbnail

๐ŸŽˆ API ์‘๋‹ต์„ ํ†ต์ผํ•ด๋ด…์‹œ๋‹ค!

๋จผ์ € response์— ๋“ค์–ด๊ฐˆ ๊ฐ’๋“ค์„ ์„ค์ •ํ•ด๋ณผ๊ฒŒ์š”!

1.๊ธฐ๋ณธ์ ์ธ httpStatus
2.์„ฑ๊ณต์ธ์ง€ ์‹คํŒจ์ธ์ง€ ๋ช…ํ™•ํžˆ ํ‘œ๊ธฐ
3.์‚ฌ์šฉ์ž ์„ค์ • code (ex. "MEM001")
4.์„ธ๋ถ€ ๋‚ด์šฉ

@Getter
@Builder
public class ErrorReasonDTO {

    private HttpStatus httpStatus;

    private final boolean isSuccess;
    private final String code;
    private final String message;

    public boolean getIsSuccess(){return isSuccess;}
}

@Getter
@Builder
public class ReasonDTO {

    private HttpStatus httpStatus;

    private final boolean isSuccess;

    private final String code;

    private final String message;

    public boolean getIsSuccess(){return isSuccess;}

}

๊ทธ๋‹ค์Œ ์‘๋‹ต์ฝ”๋“œ์˜ ENUM์—์„œ ์ƒ์†ํ•  BaseCode ์ธํ„ฐํŽ˜์ด์Šค ์„ ์–ธํ•ด ์ค„๊ฒŒ์š”!

public interface BaseCode {

    public ReasonDTO getReason();

    public ReasonDTO getReasonHttpStatus();
}

public interface BaseErrorCode {

    public ErrorReasonDTO getReason();

    public ErrorReasonDTO getReasonHttpStatus();
}

์ด์ œ ๊ฐ ์‘๊ฐ’๊ฐ’์—์„œ ์‚ฌ์šฉํ•  code ENUM๊ฐ’ ์„ค์ •ํ•ด ์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค!

@Getter
@AllArgsConstructor
public enum ErrorStatus implements BaseErrorCode {

    _INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON500", "์„œ๋ฒ„ ๋‚ด๋ถ€ ์—๋Ÿฌ"),
    _Bad_Request(HttpStatus.BAD_REQUEST, "COMMON400", "์ž˜๋ชป๋œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค"),
    _UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "COMMON401", "์ธ์ฆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค"),
    _FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON403", "๊ธˆ์ง€๋œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค"),
    //๊ฐ€์žฅ ์ผ๋ฐ˜์ €๊ธด ์‘๋‹ต

    TEMP_EXCEPTION(HttpStatus.BAD_REQUEST, "TEMP40001", "์ด๊ฑฐ๋Š” ํ…Œ์ŠคํŠธ");

    private final HttpStatus httpStatus;
    private final String code;
    private final String message;


    @Override
    public ErrorReasonDTO getReason() {
        return ErrorReasonDTO.builder()
                .message(message)
                .code(code)
                .isSuccess(false)
                .build();
    }

    @Override
    public ErrorReasonDTO getReasonHttpStatus() {
        return ErrorReasonDTO.builder()
                .message(message)
                .code(code)
                .httpStatus(httpStatus)
                .isSuccess(false)
                .build();
    }
}

@Getter
@AllArgsConstructor
public enum SuccessStatus implements BaseCode{

    _OK(HttpStatus.OK, "COMMON200", "์„ฑ๊ณต์ž…๋‹ˆ๋‹ค");

    private final HttpStatus httpStatus;
    private final String code;
    private final String message;


    @Override
    public ReasonDTO getReason() {
        return ReasonDTO.builder()
                .message(message)
                .code(code)
                .isSuccess(true)
                .build();
    }

    @Override
    public ReasonDTO getReasonHttpStatus() {
        return ReasonDTO.builder()
                .message(message)
                .code(code)
                .httpStatus(httpStatus)
                .isSuccess(true)
                .build();
    }
}

๋งˆ์ง€๋ง‰์œผ๋กœ ์‘๋‹ต์œผ๋กœ ๋ณด๋‚ผ json์˜ ๋ผˆ๋Œ€๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค!

@Getter
@AllArgsConstructor
@JsonPropertyOrder({"isSuccess", "code", "message", "result"})
public class ApiResponse<T> {

    @JsonProperty("isSuccess")
    private final Boolean isSuccess;
    private final String code;
    private final String message;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private T result;

    public static <T> ApiResponse<T> onSuccess(T result) {
        return new ApiResponse<>(true, SuccessStatus._OK.getCode(), SuccessStatus._OK.getMessage(), result);
    }

    public static <T> ApiResponse<T> onFailure(String code, String message, T data) {
        return new ApiResponse<>(false, code, message, data);
    }

}

@JsonProperty

์–ด๋…ธํ…Œ์ด์…˜์€ ๊ฐ์ฒด๋ฅผ JSON ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ Key์˜ ์ด๋ฆ„์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํด๋ผ์ด์–ธํŠธ๋Š” ์Šค๋„ค์ดํฌ์ผ€์ด์Šค, ์„œ๋ฒ„๋Š” ์นด๋ฉœ์ผ€์ด์Šค๋กœ ์†Œํ†ตํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ๋งž์ถฐ์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค!

@JsonInclude(JsonInclude.Include.NON_NULL)

๋„ ๊ฐ’์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ๋ฐ˜ํ™˜


Test

test์—์„œ ๋ฐ˜ํ™˜๋  ๊ฐ์ฒด๋ฅผ ์„ ์–ธํ•ด์ค„๊ฒŒ์š”!

public class TempResponse {

    @Builder
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    public static class TempResponseDTO {
        String testString;
    }

}

converter์—์„œ๋Š” dto๋ฅผ ์ƒ์„ฑํ•ด์ค„๊ฒŒ์š”!

public class TempConverter {

    public static TempResponse.TempResponseDTO toTempTestDTO() {
        return TempResponse.TempResponseDTO.builder()
                .testString("This is Test!")
                .build();
    }
}

controller ์ƒ์„ฑํ•ด ์ค„๊ฒŒ์š”!

@RestController
@RequestMapping("/api/temp")
@RequiredArgsConstructor
public class TempController {

    private final TempQueryService tempQueryService;

    @GetMapping("/test")
    public ApiResponse<TempResponse.TempResponseDTO> getTest() {
        return ApiResponse.onSuccess(TempConverter.toTempTestDTO());
    }
}

์„ฑ๊ณต!

profile
์ฝ”๋”ฉ์€์žฌ๋ฐŒ์–ด

0๊ฐœ์˜ ๋Œ“๊ธ€