Spring
-
Springboot와 React(Axios)에서 컨트롤러 prefix 수정하기Spring 2022. 5. 30. 20:30
어느정도 리팩토링을 마치고 ec2로 배포하려고하니 계속해서 문제가 발생한다.😖 중간중간 계속해서 실행해보고 미션 공부하면서 프로젝트에 바로바로 적용하도록 수정했으면 이리 고생하지 않았을텐데 증말 〰️ 프론트엔드와 백엔드를 각각 ec2 서버를 생성하고 리버스 프록시를 생성하고 실행하려고하니 prefix로 분리해서 요청을 보내고 싶은데,,, 원래 개발할때부터 prefix를 정해놓고 했어야했는데,,, 실행하려고 보니 이 간단한 분리도 안되어있다. (머리짚🤦♀️) 그래서 한번에 적용하려고 방법을 찾게 되었다. Springboot server.servlet.contextPath=/api Springboot에서 api prefix를 적용하는 방법은 Controller에서 @RequestMapping을 이용하여 적..
-
PUT vs PATCHSpring 2022. 3. 21. 16:48
기존 자원에 대해 업데이트를 실행하는 API중 PUT과 PATCH의 차이를 알아보자. PUT PATCH 사용 기존 자원에 대한 정보를 업데이트 할 때 자원 일부의 업데이트 정보만 담은 요청을 받을 때 넘어오지 않은 정보에 대해 null로 처리 (대상 리소스를 나타내는 데이터를 대체, 전체 교체) 넘어온 정보에 대해서만 업데이트 진행 (부분 교체) URI의 자원이 존재하지 않을 때 새로운 자원을 생성하고 정보를 반영 자원이 존재하지 않아 오류 발생 멱등성 여부 (동일할 요청을 여러번 연속으로 보내도 같은 응답으로 반응) O (넘어온 자원이 존재하지 않으면 최초 한번만 생성 후 계속 같은 값을 응답) X (자원에 대한 수정이 반복적으로 진행된다.) 멱등성 PATCH에서 멱등성이 보장되지 않는 다는 것은 무엇..
-
Repository Layer의 단위테스트 작성Spring 2022. 3. 11. 17:19
비지니스 로직은 도메인 계층에서 발생하고, 엔티티의 영속화 요구는 서비스 계층에서 발생하기 때문에 Repository의 단독 테스트를 진행하기 위해서는 Service 계층과의 관계를 끊어야 한다. SpringBoot에서는 @DataJpaTest 어노테이션을 통해서 JPA컴포넌트와 관련된 Repository의 단위테스트가 가능하도록 해준다. @DataJpaTest DataJpaTest 어노테이션은 JPA와 관련된 설정만을 로드하여 @Entity 어노테이션이 붙은 클래스를 스캔하여 저장소를 구성한다. 트랜잭션을 기본적으로 내장하고 있어 테스트 코드가 종료되면 자동으로 롤백이 이루어진다. 테스트 코드 @RunWith(SpringRunner.class) @DataJpaTest @AutoConfigureTestD..
-
테스트 진행시 @Value (application.properties.yml) 값을 읽지 못할 때 (NullPointerException)Spring 2022. 3. 4. 23:22
서비스 계층 테스트를 진행하려고 하는데 @Value값을 사용하는 경우 테스트 진행시 값이 없어 null pointer exception 이 발생하게 되었다. ( 프로퍼티 값이 로드되지 않기 때문!) ( 추가로 테스트 진행시 Mockiito를 사용하지 않는다면 @TestPropertySource어노테이션을 이용해 테스트 프로퍼티 소스를 따로 분리할 수도 있다. ) 기존 코드 @Service public class ProductService { @Value("${AWS_S3_BUCKET_URL}") private String AWS_S3_BUCKET_URL; //... } 수정한 코드 @Service public class ProductService { private String bucketUrl; publ..
-
Service 계층에서 다른 Service 혹은 RepositorySpring 2022. 3. 4. 23:01
리팩토링을 진행하던 중 Service에서 Repsitory를 직접적으로 의존하여 데이터를 찾다보니 연관관계의 데이터를 findBy 객체 찾기가 반복되게 되었다. 한 곳에 findBy를 구현하고 이 함수를 다른 Service가 의존해야 한다는 피드백을 받게 되었다. 기존의 코드 @Service public class FollowService { private FollowRepository followRepository; private UserRepository userRepository; // 직접 의존 //... //연관관계에 존재할 때마다 반복되던 코드 private User findByUserId(Integer id) { return userRepository.findById(id) .orElseTh..
-
ExistsBy쿼리를 직접 작성하기Spring 2022. 3. 4. 22:33
프로젝트 리팩토링을 진행하면서 연관관계의 데이터를 이용하여 데이터의 존재여부를 확인하는 경우가 필요하였다. JPA를 이용하면 "existsBy대상"을 통해서 작성하면 알아서 쿼리를 날려주지만, 나의 경우 처음에는 잘 작동하다가 갑자기 뒷부분의 toUserId 부분을 읽지 못하는 상황이 발생했다. (해당부분의 원인이 id를 Id로 작성하거나 대소문자의 구분이 잘 이루어지지 않아서(카멜표기법을 사용해야 함)라고 하여서 확인했으나 명확한 원인을 아직 발견하지 못했다. 😭) 우선 해결을 위하여 쿼리를 직접 구현해주어야 했다. existsBy 쿼리 작성 @Query(value = "SELECT CASE WHEN count(a) > 0 THEN true ELSE false END FROM Apple a WHERE ..
-
Validation failed for query for method public abstract 오류 발생시 (JPA)Spring 2022. 3. 4. 22:26
existsBy를 이용하여 연관관계의 데이터 아이디로 데이터 존재여부를 아는 쿼리를 작성하려고 할때 알맞은 쿼리임에도 쿼리 실패 오류가 발생했다. 기존의 코드 @Query(value = "SELECT CASE WHEN count(f) > 0 THEN true ELSE false END FROM Follow f LEFT JOIN FETCH f.fromUser a LEFT JOIN FETCH f.toUser b WHERE a.id=:fromUserId AND b.id=:toUserId") boolean existsByFromUserIdAndToUserId(Integer fromUserId, Integer toUserId); 기존코드를 보면 네이티브 쿼리로 작성되어 있으므로 수정한 코드 @Query(value..
-
CacadeType.REMOVE 와 orphanRemoval = true의 차이Spring 2022. 2. 24. 09:15
프로젝트 리팩토링을 진행하면서 연관관계의 데이터(1:N 부모 자식)에 옵션을 넣어줄 때 자식 데이터 삭제시 옵션을 주다가 궁금증이 생겨 찾아보게 되었다. CascadeType.REMOVE(부모 삭제시 자식 삭제) orphanRemoval = true(고아 객체 삭제) 공통점 (parentRepository.delete(parent)) parent의 삭제시 child도 함께 삭제시키는 것은 동일 차이점 (parent.getChild().remove()) 부모 엔티티에서 자식 엔티티 관계 삭제시 관계만 끊어질 뿐 부모 부분이 null로 들어간 자식 엔티티를 삭제하진 않는다. (parent.getChild().remove()) 부모 엔티티가 자식 엔티티의 관계를 삭제할 경우 남은 자식은 고아로 취급되어 그대로..