각종 후기/우아한테크코스

[우아한 테크코스 3기] LEVEL 2 회고 - 스프링 입문 체스 1, 2단계 미션 2차 피드백을 받아보다 (78일차)

제이온 (Jayon) 2021. 4. 20.

안녕하세요? 제이온입니다.

 

어젯밤에 2차 피드백이 오면서 오늘 검프와 함께 수정해야할 사항을 고쳐 보았습니다.

 

 

2차 피드백

 

 

첫 번째 피드백은 ResponseEntity에 CommonResponseDto를 제거하라는 것입니다. 저는 단순히 Status Code와 맞추기 위하여 수정하는 방식으로 갔었는데, 그것이 아니라 아예 이 객체를 빼라는 것이었죠.

 

 

@RestController
@RequestMapping("/api/games")
public class ChessGameApiController {

    private final SpringChessService chessService;

    public ChessGameApiController(SpringChessService chessService) {
        this.chessService = chessService;
    }

    @PostMapping
    public ResponseEntity<Object> saveChess(@RequestBody final ChessSaveRequestDto requestDto) {
        chessService.saveChess(requestDto);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PutMapping
    public ResponseEntity<Object> finishChess(@RequestBody final GameStatusRequestDto requestDto) {
        chessService.changeGameStatus(requestDto);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @GetMapping("/{name}")
    public ResponseEntity<GameStatusDto> loadChess(@PathVariable final String name) {
        return ResponseEntity.status(HttpStatus.OK)
            .body(chessService.loadChess(name));
    }

    @PutMapping("/{name}/pieces")
    public ResponseEntity<MoveResponseDto> movePieces(@PathVariable("name") final String gameName,
        @RequestBody final MoveRequestDto requestDto) {
        return ResponseEntity.status(HttpStatus.OK)
            .body(chessService.movePiece(gameName, requestDto));
    }
}

 

 

방법은 간단합니다. ResponseEntity의 Body가 없으면 Object로, 그렇지 않으면 Body의 들어갈 타입을 정해주면 됩니다. 다만, Error 처리 부분은 메시지를 보내야하므로 ErrorResponseDto로 포장했습니다.

 

 

public class ErrorResponseDto {

    private String message;

    public ErrorResponseDto() {}

    public ErrorResponseDto(final String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

}

 

 

그리고 ExceptionHandler는 다음과 같이 작성하였습니다.

 

 

@RestControllerAdvice
public class GlobalExceptionHandler {

    Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler({ChessException.class, MovementException.class,
        BlankException.class, StateException.class})
    public ResponseEntity<ErrorResponseDto> handleCustomException(final RuntimeException exception) {
        logger.info(exception.getMessage());

        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
            .body(new ErrorResponseDto(exception.getMessage()));
    }

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<ErrorResponseDto> handleException(final RuntimeException exception) {
        logger.info(exception.getMessage());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body(new ErrorResponseDto("서버 내부 에러입니다. "));
    }

}

 

 

여기서 메시지를 ErrorResponseDto로 포장하지 않고, 바로 String으로 보내면 JSON 관련 에러가 발생했습니다. 다른 스택오버플로우 글에서는 Gson을 통해 JSON으로 매핑하고 전송하면 된다고 하였으나, Gson보다는 새롭게 클래스를 포장하는 편이 낫다고 판단했습니다.

 

 

    const response = await fetch(basePath + "/api/games", option)

    if (response.status === 400 || response.status === 500) {
        const body = await response.json();
        alert(body.message);
        return;
    }

 

 

그리고 js 코드는 위와 같이 작성했습니다. 처음에 response를 받아와서 상태 코드를 확인하고, 에러라면 ErrorResponseDto가 전달되었을 것이므로 body.message를 alert해 주는 것이죠. 여기서 주의할 점은 api 통신이 정상 동작했다면 body로 넘겨받은 값이 없으므로 response.json()을 실행하면 오류가 납니다.

 

 

 

 

두 번째 피드백은 DB 테이블의 id명에 관한 것인데, 여러 테이블을 다루는 경우에는 tableName_id를 사용하는 것이 적합하다고 판단하였습니다. 그렇다 하더라도 이 부분은 취향 차이이므로 정답은 없다고 생각합니다. 링크 두 개만 공유하겠습니다.

 

 

 

Naming of ID columns in database tables

I was wondering peoples opinions on the naming of ID columns in database tables. If I have a table called Invoices with a primary key of an identity column I would call that column InvoiceID so th...

stackoverflow.com

 

 

Why do people recommend not using the name "Id" for an identity column?

I was taught not to use the name Id for the identity column of my tables, but lately I've just been using it anyways because it's simple, short, and very descriptive about what the data actually is...

dba.stackexchange.com

 

 

 

 

세 번째는 피드백은 아니고, 단순히 제가 fianl을 붙이는 이유에 대해 명확히 알고 있으라고 적어주신 것 같습니다. 이 commet를 바탕으로 불변 객체에 대해 심화 학습할 계획입니다.

 

 

정리

오늘은 검프 집에서 페어 프로그래밍을 진행했습니다. 다행히, 같이 으쌰으쌰해서 수정 사항을 성공적으로 적용하였고 더욱 완성도 높은 프로그램이 되었다고 생각합니다. 더이상 리팩토링할 부분이 보이지 않아서 이제는 갈길(?)을 가기로 하였습니다.

 

이번 미션을 통해 굉장히 많이 배워서 어떻게 정리하기도 참 어려운 것 같습니다. 일단은 어제 오늘 여러 링크나 개념들을 나열해 두고 추후 스프링 개념이 쌓였을 때 차근차근 살펴보는 것이 바람직하다는 생각이 들었습니다.

댓글

추천 글