728x90
반응형

Development/썬카(SunCar) - 개인 프로젝트 15

[썬카/정기 회고] 스프린트 3 종료 - 객체지향적 설계와 쿼리 최적화

스프린트 3이 종료되었다. 스프린트 2 회고에서 차량 등록, 조회를 어떻게 구현할지 걱정했지만 훌륭히 구현해 냈다.이번에 구현한 기능은 아래와 같다.차량 등록판매 차량 상세 조회 차량 정보를 다루는 엔티티가 무려 10개였기 때문에, 백엔드 코드 작성이 매우 매우 어려웠다. 애플리케이션 레벨에서 관계는 어떻게 정의하며, repository와 service는 어떤 구조로 작성하고 관리하는지, 쿼리는 어떻게 최적화 하는지 등등… 고민해보지 못했던 문제들을 많이 만났다. 스프린트 2의 유저 관련 로직을 짤 때보다 10배는 더 어려웠던 것 같다. 이번 스프린트 3을 진행하며 가장 크게 배운 것은 객체지향적 설계와 SOLID원칙, 그리고 쿼리 최적화이다. 백엔드에서 어려웠던 점 - 객체지향적 설계와 N+1, 카테시..

[썬카/백엔드] 판매 차량 상세조회 기능 구현 - Lazy Loading, fetchJoin(), BatchSize

차량 상세조회 기능을 구현하며 차량 관련 엔티티 10개를 조회해야 했는데, 이 과정에서 Lazy Loading, fetchJoin, BatchSize를 공부하고 적용해 보았다. 백엔드에서 쿼리 짜는 게 제일 어려운 것 같다. 아래는 Lazy Loading, fetchJoin(), BatchSize에 대해 내가 정리한 글이다.https://yskisking.tistory.com/316 JPA 쿼리 최적화 - Lazy loading, fetchJoin(), BatchSize개인 프로젝트 썬카에서 차량 상세 조회 기능을 만들다가 쿼리 최적화 문제에 부딪혔다.무려 10개의 엔티티를 전부 조회해야 했고 성능 부분을 신경쓰지 않을 수 없었기에, 자연스럽게 Lazy loadingyskisking.tistory.com..

[썬카/백엔드] 차량 관련 Facade 서비스 인터페이스 세분화 (LSP, ISP 원칙)

차량 판매등록 기능은 카히스토리 api를 사용해 받아온 데이터를 등록해야 하지만, api를 아직 도입하지 못해서(너무 비싸..) 임시로 더미 데이터를 입력하는 방식으로 구현했다. 해당 기능은 인터페이스를 통해 구현된 facade 서비스 클래스에 존재하는데, 기존엔 배포용 차량 판매등록 기능과 더미 데이터 판매등록 기능이 하나의 인터페이스에 공존하고 있었고, 그것을 두개의 구현체로 구현했었다. 배포 때는 배포 판매등록 기능, 개발 때는 더미 판매등록 기능이 이용 되어야 하며, 두 기능은 하나의 환경에서 동시에 사용되지 않아야 한다. 따라서 하나의 인터페이스에서 파생된 두 구현체는, 사용되지 않는 메서드까지 상속받아 무의미하게 구현하고 있는 상태였다( ISP 위반 ). 또한 두 구현체는 같은 부모 인터페이스..

[썬카/백엔드] 차량 판매등록 기능 구현 - 더미 데이터 생성과 객체지향적 설계

차량 판매등록 기능을 구현하며 객체지향적 설계를 한 것에 대해 정리해 보고자 한다. 차량 등록에 필요한 엔티티는 10개이며, 판매되는 자동차 1대가 10개 엔티티의 데이터를 전부 필요로 한다. 현재 차량 정보를 조회하는 카히스토리 api는 도입하지 않았기 때문에(너무 비싸..) 도입했다는 가정 하에 api 리턴값과 동일한 형태의 테이블을 설계했고, 그에 맞는 더미 데이터 생성 로직을 작성했다. 그 더미 데이터를 이용해 차량 등록 기능을 구현해 보았다. 다만 엔티티가 너무 많았기 때문에 코드가 길어졌고, 하나의 서비스 클래스에 이 모든 로직을 (엔티티 저장, dto변환, 더미데이터 생성 등) 담는 건 매우 좋지 않은 설계라고 생각되었다. 따라서 각 엔티티별 서비스 클래스에 create 메서드를 각각 만들고..

[썬카/백엔드] DTO <-> 엔티티 변환을 위한 매퍼 클래스 도입 및 적용

차량 판매등록 기능을 구현하는데, 차량 관련 엔티티 10개에 대한 반복적인 작업을 해야 했다.각 엔티티 만들고, 서비스 인터페이스 + 구현체 만들고, DTO 만들고... 전부 하나하나 일일이 해야 했다. 최대한 효율적으로 작업할 수 있는 방법은 없을까 많이 고민했지만, 엔티티 자체가 많은 거라 어쩔 수 없이 반복작업이 필요한 부분이었다. 그래도 유지보수성을 조금이라도 올리기 위해, facade 서비스 클래스를 따로 만들어서 여러 엔티티를 거치는 비즈니스 로직은 여기서 처리하고, 나머지 각 엔티티 별 서비스에서는 최대한 단일 책임 원칙(SRP)을 지켜 해당 엔티티에만 영향을 주는 로직을 작성하기로 했다. 그러나 정말 무의미하다고 느껴졌던 부분이, DTO 엔티티를 변환하기 위한 팩토리 메서드를 작성할 때였..

[썬카/정기 회고] 스프린트 2 종료 - N+1 문제

스프린트 2가 종료되었다. 6일이 걸렸으니 스프린트 1에 비해 3배는 빨리 끝났다.당연한 거겠지만 환경설정과 학습 시간이 빠지고, 기능 구현에만 집중하니 작업이 훨씬 빨랐던 것 같다.스프린트 2에서 구현한 기능은 아래와 같다.마이페이지 조회마이페이지 내 정보 수정판매중인 차량 목록 조회 프론트와 백엔드를 함께 진행하며 느낀건데, 확실히 백엔드가 좀 더 논리적으로 생각할 게 많은 것 같다. 물론 내가 백에 좀 더 신경을 쓰고 있는 것도 사실이지만, 백 로직을 생각하는 것이 3배는 머리아픈 것 같다. 백은 깊고, 프론트는 넓은 것 같다고 느꼈다. 개인적인 생각이다. 프론트엔드에서 어려웠던 점 - 다양하고 자잘한 이슈들마이페이지 조회와 내 정보 수정 기능은 백에서는 아주 수월했다. 쉽게 구현할 수 있었다. 하..

[썬카/백엔드] 차량 목록 조회 쿼리 작성 과정에서의 N+1 문제 발생과 해결

신뢰성이 중요한 중고차 거래에 필요한 차량 정보를 담기 위해서는 꽤 많은 테이블이 필요했다.차량 목록 조회 기능을 구현하는 것에만 5개의 테이블이 엮여있었고, 5개 테이블을 전부 조인해서 데이터를 가져와야 했다. 썬카는 차량 한대 당 메인 이미지 1개와 나머지 이미지들이 존재하며, 대표 이미지 여부는 is_primary 필드로 구분된다.메인 이미지는 가장 먼저 화면에 보여야 하기 때문에, 나머지 이미지들과 dto 별도의 필드에 담길 필요가 있었다.따라서 처음엔 메인 이미지를 조회한 후 나머지 이미지를 추가로 조회하는 방식으로 진행했었는데, 이 과정에서 N + 1 문제가 발생했다. N + 1문제- 최초 1번의 쿼리로 N개의 레코드를 조회한 후, 추가로 N개의 쿼리를 실행하게 되는 상황- 자동차가 10대라면..

[썬카/백엔드] Swagger를 이용한 API 명세서 도입

백엔드로써 프론트엔드와 협업하기 위해, 커뮤니케이션 비용을 줄인 효율적인 업무를 위해 API 명세서는 반드시 필요하다고 할 수 있다. 명확하게 정리된 API 명세서가 있다면 프론트엔드는 해당 자료를 참고하여 좀 더 수월하게 작업할 수 있고, 서로 엇갈려 불필요한 오류를 맞이할 일도 줄어든다.  1. 의존성 추가// build.gradledependencies { // 생략.. implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.0'} build.gradle에 swagger 사용을 위한 springdoc-openapi 의존성을 추가한다. 단 여기서 스프링 부트 버전과 openapi 버전이 반드시 호환되어야 한다.각 스프링 부트 버전마..

[썬카/백엔드] dotenv를 사용한 중요 데이터 환경변수화

# application.propertiesspring.application.name=suncar# DBspring.datasource.url=jdbc:mysql://localhost:3307/suncarspring.datasource.username=rootspring.datasource.password=0000spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.jpa.hibernate.ddl-auto=updatespring.jpa.show-sql=true# JWTjwt.secret=BTpHjyFDurb0PefLrKP+e4vKKwNCw+rUoMEpQjde7T6EzB9QjtoqC7MFVcHwbFPr+r4/OlR9ZiB5rpG0axOd4Q..

[썬카/정기 회고] 스프린트 1 종료

기능 명세서 단위로 봤을 때, 구현한 기능은 2개 뿐이다. 로그인 그리고 회원가입.무슨 이거 2개 만드는데 3주나 걸렸냐 싶겠지만, 진짜 오래 걸린 것 맞다. 처음 진행하는 개인 프로젝트다 보니 생각보다 기능구현 외에 할 일이 정말 많다는 것을 느꼈다.회사에서 잠깐 일을 했더라도, 전부 짜여진 코드의 틀 위에서 약간의 기능 추가와 수정, 관리 정도였고.. 아예 환경세팅부터 시작하는 것은 처음이었으니 그럴 만도 하겠다. 지난 3주를 돌아보면 나는 단 하루도 쉰 날이 없는데 왜 이렇게 지체되었을까 라는 의문이 든다.아침에 일어나 운동을 갔다오고, 밥 먹고 하루종일 컴퓨터 앞에만 앉아있는데 말이다. 뭐 예비군도 갔고, 가끔 술도 마셨고 그러긴 했지만 그건 큰 핑계가 되지 못한다. 3주는 너무 길다.기간이 지체..

728x90
반응형