조회수 및 권한 시스템 개선기

기록의 본질에 집중하는 플랫폼 ‘무제’는 정식 출시 이후 사용자의 이용 패턴을 분석하며 시스템의 안정성과 데이터 신뢰성을 높이는 데 주력하고 있습니다. 특히 이번 업데이트에서는 사용자가 게시물을 소비하는 가장 기본적인 지표인 ‘조회수’ 산정 방식의 개편과 더불어, 프런트엔드와 백엔드 간의 데이터 동기화 과정에서 발생한 기술적 부채를 해결한 과정을 공유하고자 합니다.

1. 지표의 신뢰성을 위한 조회수 산정 로직 개편

단순히 페이지가 로드될 때마다 수치가 증가하는 기존 방식은 새로고침 어뷰징에 취약하며 데이터의 신뢰성을 담보하기 어렵습니다. 이를 해결하기 위해 쿠키(Cookie) 기반의 중복 방지 로직을 도입했습니다.

서버 측에서는 식별용 쿠키를 활용하여, 동일 브라우저 환경에서 특정 게시물을 1시간 이내에 재방문할 경우 조회수가 중복 집계되지 않도록 제어합니다. 또한, 사용자가 게시물 목록에서 ‘더보기’를 클릭하여 실제 본문 내용을 소비하는 시점에 조회수 증가 API를 호출하도록 설계함으로써, 단순 노출이 아닌 실질적인 게시물 소비 경험을 수치화할 수 있게 되었습니다.

2. 하이버네이트 지연 로딩 예외(LazyInitializationException)의 구조적 해결

조회수 증가 로직을 추가하는 과정에서 영속성 컨텍스트의 생명주기와 관련된 기술적 난제에 직면했습니다. 벌크성 쿼리인 @Modifying 연산이 수행된 후 영속성 컨텍스트가 초기화(clear)되면서, 이후 DTO 변환 과정에서 참조하던 엔티티가 준영속 상태가 되어 LazyInitializationException이 발생한 것입니다.

이를 해결하기 위해 서비스 레이어의 작업 순서를 재배치하고, 연관된 유저 정보와 부모 게시물 정보를 한 번의 쿼리로 즉시 로딩함으로써, 영속성 컨텍스트의 상태와 관계없이 안정적으로 DTO를 생성할 수 있는 구조를 확립했습니다. 이는 예외 방지뿐만 아니라 N+1 문제를 원천적으로 차단하여 런타임 성능을 최적화하는 결과로 이어졌습니다.

3. 직관적인 카운트 단위 처리: 프론트엔드 렌더링 최적화

서비스 규모가 확장됨에 따라 큰 숫자를 사용자에게 어떻게 전달할 것인가에 대한 고민도 병행되었습니다. 천 단위가 넘어가는 조회수를 가독성 있게 표시하기 위해, 백엔드로부터 전달받은 원시 데이터를 프런트엔드에서 동적으로 포맷팅하는 로직을 구현하였습니다.

1,000단위는 ‘천’, 10,000단위는 ‘만’으로 표기하며 소수점 첫째 자리에서 내림 처리하는 방식을 택했습니다. 이 과정에서 서버의 연산 부담을 줄이기 위해 자바스크립트 클래스 내부에 포맷팅 메서드를 내장하여 처리함으로써, 서버는 순수 데이터 전달에 집중하고 클라이언트는 시각적 최적화에 집중하는 역할 분리를 실현하였습니다.

4. 권한 검증 체계의 일관성 확보 및 보안 강화

보안 측면에서는 게시물 수정 및 삭제 시 수행되는 소유권 검증 로직을 계정 식별자(이메일) 대신 서비스 내 고유 페르소나인 ‘핸들’ 기반으로 일원화하였습니다. 이는 도메인 모델의 의미론적 일관성을 확보할 뿐만 아니라, 스프링 시큐리티의 세션 관리 정책과 맞물려 더욱 견고한 인증 체계를 구축하는 토대가 되었습니다.

또한, 세션 유지 시간을 서비스 특성에 맞춰 조정하고 로그아웃 시 세션 식별자뿐만 아니라 조회수 기록 쿠키를 함께 파기하도록 설정하여, 공유 기기 환경에서도 사용자의 이용 기록이 안전하게 보호될 수 있도록 조치하였습니다.

마치며

기능을 추가하는 것보다 중요한 것은 구현된 기능이 ‘의도한 대로 정확하게 작동하는 것’이라고 생각합니다. 이번 개선 작업은 비록 눈에 띄는 화려한 변화는 아닐지라도, 서비스의 근간이 되는 데이터의 품질을 높이고 기술적 안정성을 공고히 하는 중요한 과정이었습니다. 앞으로도 무제는 신뢰할 수 있는 기록 환경을 제공합니다.

링크:
링크: » 일본어로 보기 (日本語で見る)
링크: » 영어로 보기 (Switch to English)
공유: