eco-dessert-platform / backend

Apache License 2.0
0 stars 0 forks source link

⚙️board controller 에 있는 board detail api 독립 #309

Open yunyechan9893 opened 1 week ago

yunyechan9893 commented 1 week ago

name: "✅ Feature" about: Feature 요구 사항을 입력해주세요. title: "✅ Feature" labels: ✅ Feature assignees: ''


History

🚀 Major Changes & Explanations

📷 Test Image

image

💡 ETC

shoeone96 commented 1 week ago

몇 번 언급한 적이 있지만 /api/v1/boards/{boardId}/store : 게시물에 속한 스토어 조회 이 부분의 경우 조회하려고 하는 대상이 boards가 아니라 store이기 때문에 StoreController 쪽으로 빼는 게 더 적합하지 않을까요?

Rest API에서 조회하려는 resource 기준으로 작성을 하기 때문에 요청 자원이 store일 경우 store 쪽으로 넣는 게 적합하다는 생각이 듭니다. 아무래도 저희는 서버다 보니 화면 기준이 아닌 저희가 도메인으로 삼고 있는 내용을 기준으로 정리하는 방향을 생각해봐도 좋을 것 같아요

yunyechan9893 commented 1 week ago

맞아요! 이전에도 똑같이 얘기했었는데, 아래 내용에 문제가 없다면 패키지 이동해도 괜찮을 거 같아요!

shoeone96 commented 1 week ago

말씀 주신 부분을 확인해보고 남겨드립니다!

1. RestAPI를 기준으로 Resource는 전달하고자 하는 내용물을 기준으로 보는 게 맞는 것 같습니다 예를 들어 /api/v1/boards 가 기본 게시글 전체조회인 것 처럼 해당 api는 store 정보를 반환하는 api이기 때문에 REST API 설계 원칙에 따르면 /api/v1/store/{boardId}로 만드는 것이 적절하다고 판단됩니다.

REST API의 정의와 특징을 잘 정리해놓은 글이 있어 공유드립니다.

2. board 기준으로 쿼리를 조회하는 현재 쿼리에 대한 생각 해당 쿼리 조회문을 보면 아래와 같이 작성되어 있습니다.

    @Override
    public StoreDto findByBoardId(Long boardId) {
        return queryFactory.select(
                new QStoreDto(
                    store.id,
                    store.name,
                    store.profile
                )
            ).from(board)
            .join(store).on(store.eq(board.store))
            .where(board.id.eq(boardId))
            .fetchFirst();
    }

저는 이 부분에서 board가 from 뒤에 오는 게 아니라 store가 from 뒤에 오는 게 조금 더 적절할 쿼리가 아닐까 하는 생각이 들긴 했습니다. 결국 조회를 하는 store.id, store.name, store.profile 을 어디에서 가져올 것인가가 영어 단어 그대로 from 뒤에 있는 곳에 설정되는 게 적절하다고 생각하는데 조회하는 3가지 컬럼 데이터 모두 store에 해당하는데 from board가 적절한가?에 대해 생각이 들었던 것 같아요

쿼리로 만들어보자면 아래와 같은 느낌이 조금 더 구현하고자 하는 의도에 부합한 쿼리문이 아닌가 생각이 들었습니다.

select store.id, store.name, store.profile
from store
         join product_board
              on product_board.store_id = store.id
where product_board.id = 3;

위와 같이 변경하는 것을 차치해놓더라도 결국 1번의 REST API 원칙에 따라 store 로 반환하는 게 조금 더 적절하다는 생각입니다.

결론

지금까지 설계할 때 REST API 기준에 대해 조금 소홀히 생각하고 작성한 부분이 API 전반적으로 있었던 것 같습니다. 이제 리팩토링하는 단계에서 API 관련된 부분에 조금더 체계적으로 봐야한다는 생각에 여러모로 찾아보면서 봤을 때 board에 대한 스토어 정보 조회는 /api/v1/store/{boardId} 로 변경한 뒤 StoreController에 넣는 것이 적합하다는 의견입니다.

@sikdong @sunwon12 도 같이 의견 부탁드릴게요!

수정

REST API

전달드린 콘텐츠 쭉 내려볼 때 전해드린 url의 4번에서 리소스 기준으로 서브 리소스를 판별하는 방식으로 하면 기존 방식이 맞을 것 같아요 4번에 대한 내용은 알고 있지 못한 부분이었어서 무조건 대전제로 앞에 깔린 리소스만이 중심이라고 생각했는데 그게 또 아니었네요 오늘 또 하나 배워갑니다

스크린샷 2024-11-14 오후 1 25 25

쿼리

쿼리 쪽도 의미 상 기준으로 위와 같이 설정하는 게 조금 더 의미를 잘 전달하는 쿼리가 되지 않을까 했는데 생각해보니 성능상으로 무조건 board를 from 테이블에 넣는 게 맞겠네요

기존 쿼리는 board를 from 에 넣고 where로 필터링을 거친 다음에 join 하는데 제가 생각한 쿼리는 이미 join을 한 후에 board.id를 다시 걸러내도록 동작해서 성능 문제가 있을 것 같아요

explain으로 테스트해본 결과는 동일한 것 같네요

yunyechan9893 commented 1 week ago

자료 공유 감사합니다!

도메인 이동에 따른 쿼리 수정도 함께 진행할게요~

저 역시 서브 URL 표현식이 신경 쓰였던 부분입니다.

예전에 생각으론 boards가 stores 하위에 있어야 한다고 생각하여, API가 /api/v1/stores/{storeId}/boards/{boardId} 형식으로 가야 한다고 생각했습니다. 다만 전체 페이지에서 stores/{storeId}/boards를 사용하려면 프론트엔드에서 storeId를 어떤 방식으로 전달할지 고민이 되고, stores/boards/{boardId}로 하자니 stores/boards/{boardId}와 스토어 상세 페이지의 stores/{storeId}/boards가 혼동될 여지가 있어 걱정이 많았습니다.

이 때문에 현재는 boards/{boardId}/store 형태로 설계해 두었는데요. 이 부분에 대해서는 팀원들과 함께 다시 정의해보고 수정해도 좋을 것 같습니다!

sikdong commented 1 week ago

의견 쭉 봤는데 중원님이 찾아주신 서브 URL 표현식을 봤을때 boards/{boardId}/store 이게 제일 적합해 보입니다 게시물에 속한 스토어라고 했기 때문에 게시물 -> 스토어 이 흐름이 저는 제일 적합한 거 같아요 추가로 중원님이 from Board 가 맞다고 하셨기 때문에 boardController에서 처리하는 것 또한 맞다고 생각합니다

sikdong commented 1 week ago

board controller에 역할이 너무 커져, 개발 속도 저하 이로 인해 분리를 계획함

개발 속도 저하는 무슨 의미실까요?

yunyechan9893 commented 1 week ago

의견 감사합니다!

개발 속도 저하는 boardDetail과 board가 섞여서 코드 길이가 길어져, API 찾기 어려울 때가 많더라구요.. 그래서 분리하고자 했습니다

shoeone96 commented 1 week ago

개발속도 저하보다는 유지보수 측면으로 보는 게 조금 더 작절해보이긴 합니다 👍