개발 slecs

자료요청 위젯과 카운팅을 분리하다

목차

사용자가 콘텐츠를 직접 요청할 수 있는 자료요청 위젯을 Astro 프론트엔드에 추가하면서, 그 요청을 추적하고 집계하는 별도의 카운터 서버를 구축했다.

왜 분리가 필요했나

처음엔 메인 Astro 앱 안에서 요청을 바로 처리할 수도 있었을 것 같지만, 우리 팀이 고민한 지점은 명확했다. 자료요청은 단순 UI 클릭을 넘어선다. 사용자가 요청할 때마다:

  • 요청 이력을 저장하고
  • 같은 콘텐츠에 대한 중복 요청을 집계하고
  • 어떤 자료가 가장 많이 요청되는지 추적해야 한다

메인 앱의 데이터베이스나 핸들러에 이를 바로 집어넣으면, 메인 앱의 관심사가 복잡해진다. 게다가 요청량이 증가했을 때 메인 앱의 성능까지 영향을 받을 수 있다. 그래서 전담 카운터 서버를 두기로 했다. 이렇게 하면:

  • 메인 앱은 위젯만 렌더하면 되고
  • 카운터 서버는 요청 데이터 수집과 분석에만 집중
  • 나중에 카운터 서버를 독립적으로 확장하거나 모니터링할 수 있다

구현 구조

Astro 레이아웃 계층에 ContentRequestWidget 컴포넌트를 추가했고, 사용자가 위젯과 상호작용하면 카운터 서버의 /api/psy/request 엔드포인트로 POST 요청을 보낸다.

// 가상 예시: 위젯이 보내는 요청
fetch('/api/psy/request', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ contentId, userId, requestType })
})

카운터 서버는 독립 Node.js 앱으로 돌아가면서, 그 request 엔드포인트에서:
- 요청 데이터를 받아서
- 데이터베이스에 기록하고
- 필요하면 실시간 집계 업데이트

package.json 갱신은 카운터 서버의 의존성을 추가한 것이고(아마 express, body-parser 같은 기본 라이브러리들), server.js 수정은 그 엔드포인트를 구현한 부분이다.

마이크로 아키텍처의 첫 발걸음

이 작업이 흥미로웠던 건, 프론트엔드 위젯과 백엔드 서비스의 경계를 명확히 했다는 점이다. 팀원들과의 코드리뷰에서 나눈 얘기가 있었다:

  • "이 엔드포인트는 누가 호출하나?" → 명확하게 자료요청 위젯만
  • "요청 실패하면 어떻게 하나?" → 프론트에서 재시도 로직 + 카운터는 멱등성 보장
  • "로그와 모니터링은?" → 카운터 서버만 보면 되니까 더 직관적

비슷한 기능을 나중에 추가할 때도 이 패턴을 따르면 되겠다는 합의가 생겼다. 예를 들어 "댓글 감정" 추적이나 "클릭 히트맵" 같은 것도 같은 방식으로 카운터 서버에 추가할 수 있다.

회고

Base.astro 레이아웃에 위젯을 심은 이유는, 사이트 전역에서 요청이 가능해야 했기 때문이다. 만약 특정 페이지에만 필요했다면 각 페이지에서 import 했을 텐데, 비즈니스 요구사항이 "모든 페이지에서 자료를 요청할 수 있어야 한다"는 거였다. 초반에 그 범위를 팀과 명확히 하는 게 얼마나 중요한지 다시 느꼈다.

또 하나 배운 건, 초기 분리가 기술 부채를 줄인다는 것. 나중에 "자 이제 요청 기능을 따로 빼자"라고 리팩토링하면 훨씬 비싼 비용이 들지만, 처음부터 경계를 그으니 수정이 쉽고 테스트도 단순하다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.