[Toy Project] 일관된 HTTP 상태 코드 및 메시지 관리하기

최지나·2024년 1월 8일
2
post-thumbnail

적용 배경

  • 제품 관련 Toy 프로젝트를 진행하다보니, errorCode와 response가 객체만 다를 뿐, 에러 코드와 에러 메시지가 반복되는 것을 확인할 수 있었다. 일관된 응답 처리를 하면, 유지보수성이 좋아지고, 확장성도 커지기때문에 ResponseCode enum을 생성해 상태 코드와 메시지를 관리해보고자 했다

통일된 HTTP 상태 코드 관리의 장점

  • 일관성 : API 응답에서 일관된 메시지와 상태 코드를 사용할 수 있다
  • 유지보수: 중앙에서 메시지와 상태 코드를 관리하므로, 변경 사항이 있을 때 쉽게 업데이트
  • 국제화 지원 : 다양한 언어로 메시지를 쉽게 변환할 수 있는 기반을 마련

코드

  • ResponseCode.java
@Getter
public enum ResponseCode {

    SUCCESS(HttpStatus.OK, "{0}에 성공하였습니다"),
    RETRIEVED(HttpStatus.OK, "{0} 조회에 성공하였습니다."),
    UPDATED(HttpStatus.OK, "{0} 업데이트에 성공하였습니다."),
    CREATED(HttpStatus.CREATED, "{0}이(가) 생성되었습니다."),
    DELETED(HttpStatus.NO_CONTENT, null),

    UNCHANGED(HttpStatus.NO_CONTENT, "{0}은(는) 변경 사항이 없어 업데이트되지 않았습니다."),
    CONFLICT(HttpStatus.CONFLICT, "{0}이(가) 이미 존재합니다."),
    BADREQUEST(HttpStatus.BAD_REQUEST, "{0}."),
    NOTFOUND(HttpStatus.NOT_FOUND, "{0}을(를) 찾을 수 없습니다.");

    private final HttpStatus status;
    private final String message;

    private ResponseCode(HttpStatus status, String message) {
        this.status = status;
        this.message = message;
    }

    public String getMessage(String... args) {
        return MessageFormat.format(this.message, (Object[]) args);
        // message의 {0} 자리 대신 들어갈 String을 input으로 받는다
    }

    public HttpStatus getStatus() {
        return this.status;
    }

    public int getCode() {
        return status.value();  // status에 해당하는 코드를 가져온다 ex) 200
    }

}
  • CategoryController.java
@Operation(summary = "Register new Category")
  @ApiResponse(content = @Content(schema = @Schema(implementation = CommonRes.class)))
  @PostMapping
  public ResponseEntity<Object> create(
      @RequestBody @Valid CategoryInput categoryInput) {
    try {
      categoryService.createCategory(categoryInput);
      return ResponseEntity
          .status(ResponseCode.CREATED.getStatus())
          .body(new CommonRes(ResponseCode.CREATED.getCode(), ResponseCode.CREATED.getMessage("카테고리")));
    } catch (ResponseStatusException ex) {
      return ResponseEntity
          .status(ex.getStatusCode())
          .body(new CommonRes(ex.getStatusCode().value(), ex.getReason()));
    }
  }

느낀점

  • enum 정의하는데는 오래 걸리지 않았지만, 전체 controller, service 상에서 enum을 적용하는데는 꽤 많은 시간이 걸렸다,,,

  • 물론 formatting을 변경하면서 바뀐 부분도 있었지만, 21개의 파일을 바꾸는 건 쉬운 일이 아니었다
  • 다음 프로젝트를 진행할 때는 미리 공통된 ErrorCode와 ErrorMessage를 정의하고, 이를 바탕으로 API를 만들어봐야겠다!!
profile
의견 나누는 것을 좋아합니다 ლ(・ヮ・ლ)

0개의 댓글