TIL

    [TIL-231219] 사용자 정의 애노테이션을 사용한 List 요소 검증

    💻문제점 게시글 등록 API 요청 시에는 요청 바디에 title, content, imageUrls, tags 필드를 포함해야 한다. public record PostAddRequest( @NotBlank @Length(min = 1, max = 20) String title, @NotBlank @Length(min = 1, max = 1000) String content, @Size(max = 5) List imageUrls, @Size(max = 5) List tags) {} 이러한 데이터를 받을 때, 각 항목에 대한 유효성 검증을 해야한다. 특히 tags와 같은 리스트 형태로 전달되는 여러 문자열 각각에 대한 길이 검증이 필요했다. 기존의 애노테이션을 사용한 검증 방식으로는 리스트의 각 요소에 대한..

    [TIL-20240307] 주간/월간/연간 섭취량 조회 API 성능 개선

    💻기존 코드주간 섭취 칼로리 조회 API는 요청한 주의 각 요일에 대한 MealType별 칼로리 값과, 전체 합산 칼로리 값을 반환한다.월간/연관 섭취 칼로리 조회 API 역시 다음 메서드를 활용한다. IntakeNutrientsService public List searchWeeklyIntakeCalories( Long memberId, LocalDate startDate, LocalDate endDate) { memberQueryService.search(memberId); return startDate .datesUntil(endDate.plusDays(1)) .map( ..

    [TIL - 20240110] 컨트롤러 나누기?!

    💻문제점 현재 MemberController 클래스만 보아도 회원 가입, 프로필 수정, 섭취량 조회 등 다양한 기능을 MemberController에서 수행한다. 너무 많은 기능이 MemberController에 존재한다. @RestController @RequiredArgsConstructor @RequestMapping("api/v1/members") public class MemberController { private final MemberService memberService; private final MemberQueryService memberQueryService; private final NutrientsQueryService nutrientsQueryService; private fin..

    [TIL - 20240103] Spring Data JPA @Modifying 문제

    💻문제점 public interface CommentRepository extends JpaRepository { @Modifying @Query("UPDATE Comment c SET c.member = NULL WHERE c.member.id = :memberId") void setMemberToNull(Long memberId); } @Modifying 애노테이션은 @Query 애노테이션으로 작성된 INSERT, UPDATE, DELETE와 같은 쿼리에 사용됩니다. (SELECT제외) @Test @DisplayName("회원이 작성한 댓글의 Member를 null로 변경") void setMemberToNullTest() { // given Member otherMember = MemberFixtu..

    [TIL - 20231228] Interface의 default 메서드를 활용한 Enum 확장

    💻문제점 Enum 값에 숫자 값을 넣어주기 위해 다음과 같이 setCalorie()를 선언했다. 문제는, OVER_INTAKE 밖에 사용되지 않는 메서드이기 때문에, 그 외에는 Enum의 message만 반환하는 점이 어색함이 많았다. NotificationMessage.java @Getter public enum NotificationMessage { // sse SSE_CONNECTION("SSE 연결이 완료되었습니다."), // intake OVER_INTAKE("오늘의 칼로리 섭취량이 %dKcal 초과되었습니다."); private final String message; NotificationMessage(String message) { this.message = message; } public ..

    [TIL - 20231226] jacoco 패키지, 클래스 Report에서 제외

    💻문제점 jacoco 코드 커버리지 적용했다. 이제 jacoco Report에 추가하지 않을 패키지나 클래스를 제외해보자. 🔍해결 build.gradle jacocoTestReport { reports { html.required = true xml.required = false csv.required = false } excludedClassFilesForReport(classDirectories) dependsOn test finalizedBy 'jacocoTestCoverageVerification' } jacocoTestCoverageVerification { excludedClassFilesForReport(classDirectories) violationRules { rule { element..

    [TIL - 20231222] AuthenticationEntryPoint를 사용한 JWT 예외 핸들링

    💻문제점 JwtAuthenticationFilter.java @Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String extractToken = request.getHeader(JwtUtils.AUTH_TOKEN_HEADER); jwtUtils.extractBearerToken(extractToken) .ifPresent( jwt -> { jwtUtils.validateToken(jwt); if (SecurityContextHolder.getContext()..