[Spring] redoc + swagger를 활용한 API 문서화 (2)
·
Programming/Spring boot
연동 과정 일단 필요한 의존성과 설정값들을 추가해준다. 버전의 경우는 본인 spring boot와 호환 되는 버전을 선택해서 해주면 된다.pom.xml org.springdoc springdoc-openapi-ui 1.6.4 application.ymlspringdoc: api-docs: enabled: true path: /v3/api-docs swagger-ui: enabled: true path: /api/swagger-uiReDoc은 OpenAPI JSON을 가지고 문서를 렌더링 하기 때문에 경로 지정을 해줘야 한다. Swagger의 경우 경로 지정을 안하면 기본 url로 접속이 되지만, 내 프로젝트의 경우 인증 절차 없이 루트 바로 하위 url로 접근..
[Spring] redoc + swagger를 활용한 API 문서화 (1)
·
Programming/Spring boot
입사 후 느낀 문제 중 하나는 문서의 부재였다. 토이 프로젝트라면 모를까, 실제로 상용 중인 서비스를 명세서 없이 유지보수하는 일은 아무래도 위험 부담이 컸다. 프론트와 백엔드를 모두 내가 맡고 있어 의사소통 문제가 생길 일은 없지만, 새로운 API를 만들거나 기존 기능을 수정하려면 수많은 기능을 다시 살펴봐야 했다. 문서가 없다 보니 무엇을 참고해야 하는지, 이 기능이 어떤 입력과 출력을 사용하는지를 매번 코드로 직접 추적해야 했고, 그 과정에 드는 시간이 점점 커지고 있었다. 어차피 계속 담당하게 될 업무라면 차라리 내가 기준을 하나 만들어두는 게 맞다고 판단했고, 그렇게 API 명세서를 직접 정리해보기로 했다. 아래는 그 과정을 간단히 정리한 내용이다. API 명세화API 명세서는 API를 이해하고..
[MySQL] 대소문자 구분 - collation
·
Programming/SQL
문제 상황.findByCustomerAndField()를 통해 값을 찾은 후 존재하면 수정, 없으면 추가를 하는 로직을 작성했었다. (회사 특성상 JPA를 온전히 받아쓰지 않기 때문에 기존값이 존재할 때 save를 치면 자동으로 update가 되지 않고 충돌 에러가 발생함) 해당 테이블의 pk는 auto increament 방식으로 생성되므로 조회시에는 의미상 유일성을 보장할 수 있는 필드들의 조합을 조건으로 사용했다. 값 적재 및 조회 테스트를 마친 후 수정 테스트를 돌리던 와중에 에러가 발생했다. Incorrect result size: expected 1, actual 2findBy 메서드에서 두 개의 컬럼 값을 조건으로 조회하는 과정에서 중복 데이터 관련 오류가 발생했다.하지만 실제로 데이터베이스..
[Spring] batch insert 를 통한 성능 개선
·
Programming/Spring boot
업무 진행 도중 최소 1년치 ~ 최대 3년치의 데이터를 한번에 디비에 적재시켜야 하는 상황이 있었다. 늘 그래왔듯 save()를 통해 insert를 진행하려 하였으나, 한번에 들어가는 데이터의 양이 꽤나 많았기 때문에 속도적으로 너무 하자가 있었다. 이 기회에 Spring Batch Insert에 대해 알아보자 싶어서 코드에 적용해보았다. Batch Insert 개념일반적인 Insert는 하나의 row를 개별적으로 적재시키는 반면, Batch Insert는 다수의 row를 일괄적으로 적재시키는 방법이다. 쿼리 실행 후 응답을 받야 다음 쿼리를 진행할 수 있다는 점을 생각해보면 Batch Insert는 성능적으로 꽤나 많은 이점을 갖는다. 그럼 모든 쿼리를 다 Batch로 처리하면 되지 않겠느냐 생각할..
[Spring] DB connection Pool 끊김 문제
·
Programming/Spring boot
한창 레거시 코드 수정을 진행하던 와중 DB 커넥션이 끊기면서 에러가 발생했다. 기존에 stream으로 짜여있던 코드를 병렬처리되게끔 변경하다 발생한 문제였기 때문에 해당 코드 위주로 문제를 살펴보았다. 아래는 해당 문제상황 파악 및 해결 과정에 대해 정리한 글이다. HikariCP 커넥션 풀 고갈 com.mysql.cj.jdbc.exceptions.CommunicationsException: The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.당시 발생한 로그를 살펴보 MySQL과의 커넥션 중 가용한것이 없어서 ..
[Java] 자바 Collection 정리
·
Programming/JAVA
Collection 개념컬렉션이란 많은 수의 데이터를 그 사용 목적에 적합한 자료구조로 묶어 하나로 그룹화한 객체를 말한다. 자바에서는 이러한 컬렉션을 위한 인터페이스와 클래스들이 존재하며 그 종류는 아래와 같다. 1. List : 순서에 따라 데이터를 관리하며 중복을 허용한다.2. Set : 순서가 존재 하지 않으며 중복을 허용하지 않는다.3. Map : 데이터를 Key : Value 쌍으로 관리한다. 이때 Key는 중복이 불가하고 Value는 중복이 가능하다.4. Queue : 데이터를 FIFO 방식으로 관리한다. 5. Stack : 데이터를 LIFO 방식으로 관리한다. Collection 활용컬렉션 클래스를 사용하기 위해선 데이터가 객체여야만 한다. int, float, char 같은 기본 자..
[Spring] 리팩토링 - 객체 생성 방식
·
Programming/Spring boot
코드의 개선 사항이 필요해보인다면 언제든 댓글로 지적해주세요 :) Ver.1서비스 계층에서 생성자를 통해 인스턴스 생성서비스 계층에서 비즈니스 로직 뿐만아니라 객체 생성 역할까지 수행또한 여러 메서드에서 동일한 객체를 생성해야 하는 경우, 코드가 불필요하게 중복됨객체 생성 로직이 변경되는 경우, 작성된 모든 코드를 찾아서 변경해야함CartItemEntity cartItem = new CartItem(targetType, targetId, amount); Ver.2엔티티 내부에 정적 팩토리 메서드를 작성하여 객체 생성의 책임을 엔티티에 둠Entity가 Dto의 구조를 알고있어서 의존하게 됨(결합도 증가)// Entitypublic static CartItemEntity create(CartItemDto c..
[Spring] @Scheduled와 JavaMailSender를 이용한 자동 메일 발송 기능
·
Programming/Spring boot
코드의 개선 사항이 필요해보인다면 언제든 댓글로 지적해주세요 :) 기능 구현 요구 사항사용자는 로또 예상 번호를 입력할 수 있다.이미 당첨 번호가 공개된 로또 회차는 입력 불가하다.매주 토요일 저녁 예상 번호와 당첨 번호를 비교한다.이메일 알림을 허락한 사용자에 한해서 이메일 발송을 진행한다.유저 테이블에 저장된 이메일 정보는 이미 검증이 완료 된 상태라고 가정한다.이메일에는 당첨 여부, 일치하는 개수 등의 정보를 기재한다.  Entity와 Dto, Repository 코드는 더 이상 보여줄 필요가 없을 것이라 생각되어서 사용한 주요 Spring 기능 소개와 적용한 로직의 일부만을 포스팅할 예정이다. JavaMailSender스프링 프레임워크에는 이메일을 쉽게 보낼 수 있는 모듈인 Spring Boot ..
[Spring] 장바구니 기능 구현
·
Programming/Spring boot
코드의 개선 사항이 필요해보인다면 언제든 댓글로 지적해주세요 :) 구현하려는 장바구니 기능의 요구사항은 다음과 같다.사용자는 두 종류의 장바구니를 가진다. IsLotto(true : 금액 제한 장바구니, false :  무제한 장바구니)장바구니 사용자는 현재 인증된 토큰을 기반으로 찾는다.장바구니 상품 추가 시엔 상품 id, 상품 수량, IsLotto 값, 상품 종류(enum) 값이 필요하다.장바구니 물품 id를 반환해준다.isLotto가 true 일 경우, 담은 금액이 제한 금액(최신 회차 로또 실수령액)을 넘길 경우 에러를 반환한다.장바구니 조회 시엔 IsLotto 값이 필요하다. (default : true)조회할 장바구니가 없다면 새로 생성한다.장바구니 상품 제거 시엔 장바구니 물품 id 값이 필..
[Spring] 로또 API 단위 테스트 코드 작성
·
Programming/Spring boot
코드의 개선 사항이 필요해보인다면 언제든 댓글로 지적해주세요 :)  일반적으로 테스트 케이스를 작성한다고 하는건 거의 단위 테스트를 의미하는 것이다.통합 테스트는 여러 컴포넌트들 간의 상호작용과 호환성을 검증하는 테스트이기 때문에 테스트를 위한 비용이 많이 소모된다. Java를 테스트 할 때 가장  흔히 사용되는 프레임워크인 JUnit을 사용해서 단위 테스트를 진행할 예정이다. 단위 테스트 : 하나의 모듈을 기준으로 독립적으로 검증하는 테스트 (controller, service, repository, ...)테스트 코드 실행 시간이 빠름하나의 테스트가 곧 하나의 문서로 역할독립적인 검증이기 때문에 다른 객체와의 상호작용 필요시 가짜 객체를 정의해 주어야 함가짜 객체의 답변을 직접 작성해주는 것이기 때문..
[Spring] 테스트 코드 기본 개념
·
Programming/Spring boot
테스트 코드 개념API를 개발하면서 swagger나 postman을 통해 개발 사항에 대한 테스트를 진행해 볼 수 있다. 하지만 이렇게 수동적인 테스트는 관리해야할 api가 늘어나고, 요구사항이 변경되게 될수록  커버하지 못하는 영역이 늘어나게 된다. 이를 위해 필요한게 테스트 코드이다. 테스트 코드를 통해 개발자는 빠른 피드백을 얻을 수 있으며, 테스트 케이스 수행을 자동화할 수 있다. 이에 따라 코드의 안정성이 높아져 소프트웨어 품질 유지에 도움이 되는 것이다. 테스트 코드 규칙이러한 테스트 코드는 다음과 같은 규칙들을 지키며 작성할수록 좋은 테스트 코드라 불려진다FIRST 원칙Fast :  빠르게 실행Isolated : 테스트 코드 성공 유무가 다른 테스트에 영향을 끼치지 않음Repeatable :..
[Spring] 로또 API 구현(2) & 예외 처리(@validate)
·
Programming/Spring boot
코드의 개선 사항이 필요해보인다면 언제든 댓글로 지적해주세요 :) 이번 API는 각 년도별로 누적된 로또 번호의 통계치를 제공해주는 api이다. 크게 보면 Lotto정보에 속하는 것이기 때문에 service와 controller 코드를 같은 클래스에 작성하였었으나, 단일 책임 원칙에 따라 분리하여 작성하였다. 코드를 작성하면서 팀원이 작성해둔 예외처리메서드를 사용하여 예외처리를 진행해주었다. try-catch 사용은 최대한 지양하는게 좋다는 말을 들어왔기에 throw하여 @RestControllerAdvice에서 받게끔하였다. Entity & DTO@Getter@Setter@Mapping(mappingPath = "statnum-mapping.json")@Setting(settingPath = "elas..