Skip to content
J_Coder edited this page Dec 4, 2024 · 54 revisions

🎍 개발자들의 이야기가 자라나는 곳, 데나무

💪 기술적 도전

Important

더 자세한 내용은 NOTION에서 확인이 가능해요! 보러 가시겠어요? 팀 노션 보러가기

RSS 기반 블로그 구독

RSS 기반 FEED 크롤링 이미지

Note

RSS 링크만으로 간편하게 블로그를 등록할 수 있어요. 등록된 블로그의 새로운 글이 30분 간격으로 자동 업데이트되어 데나무에 노출되어요.

🗝️: Crawling, RSS, Cron

RSS Crawler

  1. 클라이언트로부터 블로그 등록 기능을 통해 RSS 블로그 링크 신청 받기
  2. 관리자 권한으로 신청된 블로그 승인/거절을 통해 결과 HTML 이메일 발송
  3. 승인 시, 서비스 DB에 RSS URL 저장
  4. PM2의 CRON 기능을 이용하여 30분 마다 서비스 DB에 저장되어 있는 RSS URL에서 RSS XML 획득
  5. XML 파싱을 한 후 30분 이내의 게시글만 필터링 할 수 있도록 시간 연산을 통해 필터링
  6. 게시글 작성 시간 순으로 정렬 후 서비스 DB에 게시글 정보들 저장
  7. 최신으로 가져온 피드들은 Redis에 저장하여 Polling으로 데이터를 가져갈 때, 더 빠르게 접근할 수 있도록 최적화

무한 스크롤

무한 스크롤 GIF

Note

모든 컨텐츠를 휠 스크롤 하나로 제공받을 수 있어요. 시간 상관 없이 데나무 서비스에 등록되었던 오래된 게시글 또한 확인할 수 있어요.

🗝️: React Query Caching, Pagination, lazy Loading

FE

  • React Query Caching을 통해 컴포넌트 로딩 시간 단축
  • Image Lazy Loading을 도입하여 웹 사이트의 로딩 시간 단축
  • 무한 스크롤 도입

BE

  • 페이지네이션에서 제공한 마지막 게시글부터 LIMIT를 제한하여 다음 페이지 정보 제공
  • OFFSET 기반의 페이지네이션을 사용했을 때, 중복되거나 사라지는 데이터 존재 가능성을 제거하기 위한 목적

최신 피드 제공

최신 피드 제공 Polling

Note

새로고침 없이도 Polling 통신 방식을 이용하여 30분 간격으로 새로운 피드가 탐지될 경우 클라이언트에게 제공해줘요.

🗝️: 자체 조회수, Polling

FE
[최신 피드 제공]

Polling vs Server Sent Event

  • 선택 결과: Polling
  • 최신 피드는 서버에서 30분에 한 번씩 업데이트
  • 30분의 긴 간격 발생할 때는 30분 동안 클라이언트와 연결하고 있어야 하는 SSE보다 Polling이 효율적이라 판단

BE
[자체 조회수]

  • 조회수 기반으로 트렌드를 제공할 때, 사용자 판별을 하지 않는다면 부정한 방법으로 조회수 획득 가능
  • 비회원 사용자를 100% 가려내는 것은 불가능
  • 쿠키, 로컬 스토리지에 데이터 저장 시 사용자가 브라우저에서 컨트롤할 수 있는 위험성 존재
  • Browser Finger Print 사용 시 브라우저 설정이 같을 가능성, 설정 값 하나만 바꿔도 새로운 사용자로 인식할 가능성 존재
  • 공인 IP를 이용하여 사용자를 파악
  • 쿠키에는 사용자가 읽은 게시글의 ID를 저장
  • 조회수 증가 API로 요청이 왔을 때, 쿠키가 있다면 DB에 접근하지 않음으로써 속도 최적화

실시간 트렌드 제공

실시간 트렌드 제공 애니메이션 GIF

Note

30초마다 업데이트되는 트렌딩 포스트를 통해 인기 있는 글을 실시간으로 확인할 수 있어요. IP와 쿠키를 활용한 중복 조회 방지 시스템으로 통계를 제공하고, 매일 자정에 트렌드가 초기화되어요.

🗝️: 자체 조회수, SSE, 비회원 식별, Cron

Server Sent Event vs Polling

  • 선택 결과: Server Sent Event
  • 트렌드는 시간에 민감함
  • Polling 보다는 Server Sent Event가 적은 횟수의 연결, 연결 해제를 시도하기 때문에 데이터 통신에서 훨씬 효율적이라 판단
  • 양방향 통신 필요성이 없음
  • Polling의 경우 Body나 Query에 데이터를 포함하여, 클라이언트 → 서버, 서버 → 클라이언트로 요청과 응답을 매번 반복
  • 트렌드는 서버 → 클라이언트 통신만 필요
  • SSE는 랭킹이 변동되었을 때만 데이터를 전송하기에 데이터 통신에서 효율성이 뛰어남

편리한 검색 시스템

검색 결과 GIF

Note

원하는 키워드로 기술 블로그 글을 쉽게 찾아볼 수 있어요. 연관성이 높은 게시글이 상단에 노출되는 유사도 기반 검색을 지원하고, 무한 스크롤로 끊김 없이 글을 탐색할 수 있어요.

🗝️: MySQL Full Text Index, Pagination, debounce

FE

  • 매번 입력에 따른 검색 API를 호출하는 것이 아닌, debounce를 적용하여 API 호출 최적화
  • 페이지네이션과 검색 결과의 키워드 강조를 통해 사용자에게 판단하기 쉬운 검색 결과 제공

BE

  • MySQL의 Full Text Index를 사용한 검색 기능 구현
  • 검색 토큰 개수를 설정하여 검색 연관도 증가
  • 페이지네이션을 이용한 검색 결과 반환

개발자 채팅

개발자 채팅 GIF

Note

실시간 채팅을 통해 다른 개발자들과 자유롭게 소통할 수 있어요. 관심 있는 기술에 대해 바로 피드백을 주고받으며 함께 성장할 수 있어요.

🗝️: Web Socket

FE

  • WebSocket을 이용한 실시간 통신
  • avvvatars-react 라이브러리를 이용한 사용자 랜덤 프로필 제작

BE

  • @woowa-babble/random-nickname 라이브러리를 이용한 사용자 랜덤 닉네임 제작
  • IP에 따라 사용자 닉네임을 24시간동안 저장
  • 24시간 후 다른 닉네임을 제공받도록 구현
  • 채팅 히스토리 20개만 Redis에 저장하여 채팅 히스토리 접근 속도 개선, 사용자 경험 향상

차트 제공

통계 그래프 GIF

Note

일별, 전체 조회수 통계를 통해 인기 있는 콘텐츠를 한눈에 파악할 수 있어요. 블로그 플랫폼별 통계를 통해 어느 개발 플랫폼이 활발한지 확인할 수 있어요.

🗝️: Graph, Statistic API

FE

  • Polling을 통한
  • 일일, 전체 조회수 통계, 블로그 플랫폼별 회원 통계를 그래프로 출력

완성도

테스트 결과

Note

서버 예외를 최대한 막으려고 테스트 코드를 꼼꼼히 짰어요. 이를 통해 사용자 경험과 생산성을 증진시킬 수 있었어요.

🗝️: Test, Exception

FE

  • React Testing Library, Vitest 테스트 구축
  • 컴포넌트 테스트로 하위 컴포넌트들에 대한 단위 테스트 작성
  • Lazy Image, Avatar 같은 공통 UI 컴포넌트, custom hook들은 Mock 객체 처리
  • lucide-react 외부 라이브러리 Mocking 처리
  • 테스트 유틸리티 헬퍼 함수 구현

BE

  • toStrictEqual vs 필요 속성만 검증의 테스트 범위 결정

    • toStrictEqual 사용의 장점
      • 응답 객체에 개발자가 예상하지 못 한 속성이 들어갈 위험성을 방지
    • toStrictEqual 사용의 단점
      • 객체의 순서를 맞춰야하는 추가 비용이 발생
    • 필요 속성 테스트만의 장점
      • 결과를 검증할 수 있는 최소 조건만을 검증할 수 있기에 유지보수 측면에서 빠르게 대응 가능
    • 필요 속성 테스트만의 단점
      • 응답 객체에 개발자가 의도하지 않은 속성이 들어갈 위험성 존재
      • 이런 속성 테스트는 E2E 테스트에서 하기엔 부적합하다고 판단 [결론]
    • 테스트는 간단 명료해야 하고, 테스트 코드 또한 유지 보수의 대상이라 판단
    • 필요 속성만 테스트를 하여 결과를 검증할 수 있는 최소 조건으로 검증
  • 앱을 최초로 1회 초기화하는 방식을 통해 테스트 코드 최적화

  • Nest class-validator의 validate를 이용하여 Request 데이터 검증 향상

  • Jest 핵심 비즈니스 로직은 E2E 테스트, 입력 값 검증은 DTO 테스트로 분리하여 유지 보수하기 쉬운 테스트 코드를 지향

  • 테스트 픽스처를 활용하여 유연한 데이터 변경에 대응

👥 팀원 역할

Backend Backend Frontend Backend Frontend
박무성 안성윤 정명기 조민석 채준혁
J103 박무성 J152 안성윤 J222 정명기 J235 조민석 J249 채준혁
당일 팀 활동 요약 담당 팀장
오프라인 미팅 장소 담당
노션 & Github Wiki 동기화 담당 멘토링 활동 담당
Github Project 칸반 보드 담당
노션 정리 담당

소개

팀 문화

회의록

1주차

2주차

3주차

4주차

5주차

6주차

기술 공유

박무성

안성윤

정명기

조민석

채준혁

팀 회고

멘토링 일지

Clone this wiki locally