728x90
반응형

2025/12 11

[Nbcam] 유저 검색 조회 속도 개선

전제데이터: 500만건조건: nickname 정확히 일치결과: 중복 없기 때문에 단건 조회테스트 환경: 조회 성능 측정 시 캐시 효과를 배제하기 위해 매번 MySQL 서버를 재시작해 동일한 스타트 환경에서 측정최초 조회 속도인덱스가 없는 상태에서 500만건중 쿼리파라미터로 들어온 값과 일치하는 단건 조회를 수행한 결과-> Filter: (u.nickname = 'zi0') (cost=529242 rows=499163) (actual time=0.0548..2733 rows=1 loops=1) -> Table scan on u (cost=529242 rows=4.99e+6) (actual time=0.0494..2589 rows=5.03e+6 loops=1)소요 시간DB 실행시간: ..

BootCamp 2025.12.22

[Spring] QueryDSL Projection 방식 비교

개요QueryDSL로 검색 API를 구현하면서 엔티티가 아닌 검색 전용 DTO로 결과를 조회해야 했다.DTO 매핑방식으로 두가지 선택지가 있다는 것을 알게되었다Projections.constructor()@QueryProjection두 방식은 결과는 같아 보이지만,안전성 · 유지보수성 · 오류 발견 시점에서 큰 차이가 있었다. Projections.constructor 방식.select(Projections.constructor( TodoSearchResponse.class, todo.title, manager.id.countDistinct(), comment.id.countDistinct()))특징DTO에 QueryDSL 의존성 X생성자만 있으면 바로 사용 가능설정이 간단단점 생성..

Dev./Spring 2025.12.17

[HTTP] HTTP 메서드 멱등성

DELETE 메서드는 멱등해야한다.HTTP DELETE 메서드는 원칙적으로 멱등(Idempotent) 해야 한다. 즉,“같은 DELETE 요청을 여러 번 보내도 서버의 최종 상태는 동일해야 한다.”예를 들어 /todos/1/managers/10 을 삭제할 때:첫 번째 요청 → manager 정상 삭제두 번째 요청 → 이미 삭제된 상태지만서버의 최종 상태는 동일(삭제됨)실패가 아니라 성공처럼 처리내가 받은 피드백의 핵심 - 두 번째 DELETE 요청이 실패하면 UX가 깨진다다음과 같은 피드백을 받았다.ManagerController delete 메소드의 인증된유저 처리 문제 에서 HTTP Method중 DELETE는 멱등성을 준수합니다. 제공하는 기능에 따라 멱등성을 준수하지 않도록 만들어야 할 수 도 있..

Network./Server. 2025.12.10

[Spring] Spring Security + JWT로 로그인 기능 구현

전체적인 흐름 클라이언트가 /auth/login 으로 이메일/비밀번호 전송서버에서 사용자 검증 후 JWT 발급이후 요청들은 Authorization: Bearer token헤더에 JWT를 담아서 호출커스텀 JwtAuthFilter가 토큰을 검증하고 userId를 꺼냄@AuthUser 파라미터로 컨트롤러에 userId를 바로 주입→ 컨트롤러/서비스는 JWT 구조를 모른 채 로그인된 사용자 ID만 다룸설계JwtUtil - JWT 생성 및 검증역할토큰 생성토큰 검증Claims / subject 추출설계 기준subject에는 userId를 넣음 (주 식별자)claim으로 email 정도만 추가validate()는 예외 캐치로 단순 처리@Componentpublic class JwtUtil { @Value(..

Dev./Spring 2025.12.09

[Spring] Transactional 사용시 자가호출(Self-Invocation)이슈

문제다음과 같은 코드에서,한 메서드 안에서 다른 @Transactional 메서드를 호출하면나는 REQUIRES_NEW가 적용되어 별도 트랜잭션이 만들어질 것이라고 기대했다.그러나 실제 동작은 전혀 달랐다.@Service@Slf4j@RequiredArgsConstructorpublic class OrderService { private final StockService stockService; private final PaymentService paymentService; private final PaymentRepository paymentRepository; private final OrderRecordService orderRecordService; @Transaction..

Dev./Spring 2025.12.08

[Spring]왜 Security 의존성을 추가하면 API 호출시 401이 뜰까

기존에 잘 돌아가던 demo 프로젝트에 Security 의존성을 추가하니 모든 API 호출시 401에러가 떴다. 왜 의존성 추가 하나만으로 잘 돌아가던 서버가 에러를 뱉는걸까?Security의 기본 보안 정책 자동 활성화Spring Security는 의존성 추가만으로도 다음 설정을 자동 적용 모든 요청은 인증 필요인증되지 않은 요청은 → 401 UnauthorizedForm 로그인 페이지가 자동 생성됨기본 사용자 계정이 자동 생성됨 (username=user, password=콘솔에 출력)즉 security가 추가되며 모든 요청을 가로막은 것이다.Security를 추가한 후의 동작 흐름왜 401일까?Spring Security가 요청을 Controller로 보내기 전에 차단하기 때문 , 컨트롤러에 도달하..

Dev./Spring 2025.12.06

[Nbcam] Level6 정의하고 해결한 문제

1. ManagerController delete 메소드의 인증된유저 처리 문제문제기존 deleteManager 메서드 에서는컨트롤러가 JWT 구조를 알고있음Authorization Header를 직접 읽고 jwtUtil을 직접 사용 @DeleteMappingpublic void deleteManager( @RequestHeader("Authorization") String bearerToken, @PathVariable long todoId, @PathVariable long managerId) { Claims claims = jwtUtil.extractClaims(...); long userId = Long.parseLong(claims.getSubject());}Contr..

카테고리 없음 2025.12.05

[Nbcam] 심화 주차 Level5 AOP를 활용해 특정 API 로깅 구현

Interceptor 또는 AOP를 활용하는 부분이라 나는 AOP 구현을 선택했다.조건AOP를 사용하여 구현하기어드민 API 메서드 실행 전후에 요청/응답 데이터를 로깅합니다.로깅 내용에는 다음이 포함되어야 합니다:요청한 사용자의 IDAPI 요청 시각API 요청 URL요청 본문(RequestBody)응답 본문(ResponseBody)@Around 어노테이션을 사용하여 어드민 API 메서드 실행 전후에 요청/응답 데이터를 로깅합니다.요청 본문과 응답 본문은 JSON 형식으로 기록하세요.로깅은 Logger 클래스를 활용하여 기록변경 파일 상세 설명AccessCheckAOP역할어드민 전용 API 접근 시점에 실행되는 AOP요청 정보 수집 로그로 기록컨트롤러/서비스 로직과 로깅 관심사를 명확히 분리Pointcu..

카테고리 없음 2025.12.04

[Spring] AOP 정리

AOP란AOP (Aspect Oriented Programming) 는 여러 곳에 반복되는 공통 관심사를 비즈니스 로직과 분리해서 한 곳에서 관리하기 위한 프로그래밍 기법AOP가 왜 필요할까?예를들어 기획자가 개발자님 성능 측정을 위해 모든 메서드에 시작 시간과 종료 시간을 남기는 기능 추가해주세요라고 요청을 했을 때public void save() { log.info("start"); // 비즈니스 로직 log.info("end");}다음과 같은 코드가 모든 서비스 메서드마다 중복되면 로깅, 트랜잭션, 권한 체크 코드가 모든 메서드에 흩어짐수정하려면 전체 코드를 다 건드려야 함비즈니스 로직이 더러워짐AOP 도입 후에는 시간 측정은 AOP가 알아서 처리한다.AOP는 어디에 적용되는걸까?..

Dev./Spring 2025.12.03

[Spring] Interceptor 정리

Interceptor란Spring MVC에서 컨트롤러(Controller) 호출 전·후에 요청을 가로채서 공통 로직을 수행하는 도구JWT 기반 인증이 끝난 후, 인증된 사용자 정보(SecurityContext)를 활용해자원 소유자 검증역할 기반 접근 제어API 사용 제한등의 부가 검증 수행Spring MVC 요청 흐름[사용자 요청] ↓[JwtFilter] ↓[SecurityContextHolder에 인증 저장] ↓[Interceptor] ↓[인증 사용자 검증] ↓[Controller]Interceptor가 왜 필요할까?예를 들어 컨트롤러 마다 다음과 같은 코드가 반복된다면if (!isLogin(request)) { throw new UnauthorizedException(..

Dev./Spring 2025.12.02
728x90
반응형