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

[우아한 테크코스 3기] LEVEL 2 회고 - 지하철 노선도 관리 3단계 미션 1차 피드백을 받아 보다 (102일차)

제이온 (Jayon) 2021. 5. 14.

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

 

오늘은 오프라인으로 우테코를 진행했습니다. 오전에는 수업, 오후에는 포수타가 있고 저녁에는 제이슨 조와 회식을 하는등 여러모로 바쁜 하루를 보냈습니다.

 

 

지하철 노선도 관리 3단계 미션 피드백

사실, 피드백 자체는 어제 왔으나 저녁에 크루들과 시드집에 가서 술을 먹느라 피드백을 반영하지 못했습니다. 그래서 오늘 오전과 점심 이후 열심히 수정 사항을 반영해 보았습니다.

 

 

 

 

첫 번째 수정 사항은 Wrapper type 대신 Primitive type을 사용하여 변수를 정의하라는 것입니다. 하지만, 저는 리뷰어님의 생각과는 조금 달랐습니다. 위와 같은 id를 Wrapper type으로 정의하게 되면, 초깃값으로 0이 설정되고, DB에는 id가 정의되지 않을 경우 0이 들어갈 것입니다. 이보다는 null로 표현하는 것이 적절하다고 생각하여 저의 생각을 김고래에게 전달하였습니다.

 

김고래는 저의 생각도 옳지만, DB 테이블 내의 id 속성이 not null이므로 어차피 null 값이 들어갈 수 없다고 알려주셨습니다. 그럴 바에는 Primitive type을 사용하는 것이 더 적절하겠다고 말씀해 주셨습니다. 다만, 저는 Wrapper type이 부적합하다고 생각하지는 않아서 이러한 의견을 알아두기만 하고 수정을 안하려고 합니다. 이유는.. 이를 위해서 바뀌어야 할 코드가 너무 많았기 때문이죠.

 

 

 

 

두 번째 수정 사항은 Optional을 바로 get()하지 말라는 것입니다. 이것은 전적으로 저의 실수인데, orElseThrow()를 통해 값이 없으면 익셉션을 반환하도록 수정하였습니다.

 

 

 

 

세 번째 수정 사항은 커스텀 익셉션의 상속을 저수준의 예외를 받으라는 것입니다. 이것은 나중에 더 섬세한 계층이 생겼을 때를 대비하여 RuntimeException을 바로 상속받기보다는 IllegalArgumentException과 같은 저수준의 예외를 상속받으라는 것으로 판단하여 수정했습니다.

 

 

 

 

마지막 수정 사항은 DAO에서 Station ID들을 받아서 Station List를 만들어 반환하라는 것입니다. 어떻게 해야할 지 바로 떠오르지는 않아서 가장 쉬운 방법을 사용해 보았습니다.

 

 

    public Optional<Station> findById(final Long id) {
        final String sql = "SELECT * FROM station WHERE id = ?";
        final List<Station> stations = jdbcTemplate.query(sql, stationRowMapper, id);
        return Optional.ofNullable(DataAccessUtils.singleResult(stations));
    }
    public List<Station> findByIds(final List<Long> stationIds) {
        final List<Station> stations = new ArrayList<>();
        for (final Long id : stationIds) {
            final Station station = findById(id)
                .orElseThrow(() -> new DataNotFoundException("해당 Id의 노선이 없습니다."));
            stations.add(station);
        }
        return stations;
    }

 

 

하지만, 이 방법은 수많은 findById()를 호출하여 DB를 건드려야하므로 성능이 비효율적이라는 단점이 있습니다. 이에 대해 김고래에게 질문해 보니, "where절에 in을 사용한 query를 사용하여, 한번에 디비에서 조회하는 방향이 가능할 것 같다."라는 답변을 받았습니다. 이것은 제가 지금까지도 어떻게 in을 응용해야하는지 감이 안잡혀서 좀 더 고민해 보려고 합니다.

 

 

지하철 경로 조회 1, 2단계 미션 리팩토링

지하철 경로 조회 1, 2단계 미션 자체는 어제 제출하였지만, 미흡한 부분이 생겨서 오늘 수정해 보기로 하였습니다. 바로, 새로고침할 때마다 자동 로그아웃되는 것과 멤버 정보 수정한 다음 로그아웃해야만 정보가 갱신되는 문제였죠. 이것을 해결하는 방법은 쿠키를 사용하는 것과 localStorage를 사용하는 것이 있습니다. 저는 어제와 오늘 쿠키와 토큰의 개념을 학습한 김에 전자의 방법을 응용해 보자고 시드와 합의를 보았습니다.

 

결론적으로는 실패하였습니다. 스프링 서버 단에서 Response의 헤더로 Set-Cookie에 토큰을 넣어주었지만, 브라우저 단에서 쿠키를 저장하지 않는 문제가 있었습니다. 이것을 해결하기 위해 여러 크루들과 이야기도 하고 구글링도 해 보았지만, 해결 방법을 결국에는 찾지 못해서 일단은 localStorage를 이용하기로 하였습니다. 쿠키를 사용한 코드는 제가 실수로 roll-back을 해 버리는 바람에 전문은 작성하지 못할 듯합니다.

 

 

정리

이후에는 제이슨과 포츈, 라이언, 아마찌, 찰리, 영이와 함께 삼겹살을 먹으러 갔습니다. 크루들과 다양한 이야기를 하면서 웃을 수 있어서 좋았고, 이러한 기회를 만들어 주신 제이슨에게 정말 감사합니다 ㅎㅎ

댓글

추천 글