인스타그램을 벤치마킹한 SNS 프로젝트
Fiesta 바로가기
- 제작 기간 : 2022년 10월 18일 ~ 12월 10일
- 참여 인원 : 5인 팀 프로젝트
- 프로젝트 개요
- 인스타그램을 벤치마킹한 SNS 프로젝트
- 타임라인, 채팅, 탐색(해시태그, 팔로우) 등 SNS에 최적화된 기능 제공
- 담당 기능
- 전체 프로젝트 기획 및 개발 참여
- 로그인, 회원가입, 비밀번호 재설정 등 회원 관련 기능
- bcrypt를 활용하여 비밀번호 암호화
- ajax를 활용하여 아이디/닉네임 중복검사, 유효성 검사
- 이메일 인증
- 검색 기능 및 AJAX를 활용한 검색 결과 페이지 조회
- 웹, 태블릿, 모바일별 미디어 쿼리 적용
- 계정, 해시태그 팔로우 기능
로그인, 회원가입, 비밀번호 재설정 등 회원 관련 기능
- 검색 기능 및 AJAX를 활용한 검색 결과 페이지 조회
- 페이지네이션을 활용하여 무한 스크롤 구현
- 웹, 태블릿, 모바일별 미디어 쿼리 적용
- 계정, 해시태그 팔로우 기능
- 회원 관련 기능
- 로그인, 회원가입, 비밀번호 재설정
- 검색 결과 페이지
- 팔로잉, 계정 조회, 게시글 조회를 한 번에
핵심 기능 설명 펼치기
-
저는 이 서비스가 페이스북이나 인스타그램 처럼 가볍게, 자주 사용되길 바라는 마음으로 개발했습니다.
때문에 페이징 처리도 무한 스크롤을 적용했습니다. -
하지만 무한스크롤, 페이징 혹은 “더보기” 버튼? 어떤 걸 써야할까 라는 글을 읽고 무한 스크롤의 단점들을 알게 되었고,
다양한 기준(카테고리, 사용자, 등록일, 인기도)의 게시물 필터 기능을 넣어서 이를 보완하고자 했습니다. -
그런데 게시물이 필터링 된 상태에서 무한 스크롤이 동작하면,
필터링 된 게시물들만 DB에 요청해야 하기 때문에 아래의 기존 코드 처럼 각 필터별로 다른 Query를 날려야 했습니다.
기존 코드
/**
* 게시물 Top10 (기준: 댓글 수 + 좋아요 수)
* @return 인기순 상위 10개 게시물
*/
public Page<PostResponseDto> listTopTen() {
PageRequest pageRequest = PageRequest.of(0, 10, Sort.Direction.DESC, "rankPoint", "likeCnt");
return postRepository.findAll(pageRequest).map(PostResponseDto::new);
}
/**
* 게시물 필터 (Tag Name)
* @param tagName 게시물 박스에서 클릭한 태그 이름
* @param pageable 페이징 처리를 위한 객체
* @return 해당 태그가 포함된 게시물 목록
*/
public Page<PostResponseDto> listFilteredByTagName(String tagName, Pageable pageable) {
return postRepository.findAllByTagName(tagName, pageable).map(PostResponseDto::new);
}
// ... 게시물 필터 (Member) 생략
/**
* 게시물 필터 (Date)
* @param createdDate 게시물 박스에서 클릭한 날짜
* @return 해당 날짜에 등록된 게시물 목록
*/
public List<PostResponseDto> listFilteredByDate(String createdDate) {
// 등록일 00시부터 24시까지
LocalDateTime start = LocalDateTime.of(LocalDate.parse(createdDate), LocalTime.MIN);
LocalDateTime end = LocalDateTime.of(LocalDate.parse(createdDate), LocalTime.MAX);
return postRepository
.findAllByCreatedAtBetween(start, end)
.stream()
.map(PostResponseDto::new)
.collect(Collectors.toList());
}
- 이 때 카테고리(tag)로 게시물을 필터링 하는 경우,
각 게시물은 최대 3개까지의 카테고리(tag)를 가질 수 있어 해당 카테고리를 포함하는 모든 게시물을 질의해야 했기 때문에 - 아래 개선된 코드와 같이 QueryDSL을 사용하여 다소 복잡한 Query를 작성하면서도 페이징 처리를 할 수 있었습니다.
개선된 코드
/**
* 게시물 필터 (Tag Name)
*/
@Override
public Page<Post> findAllByTagName(String tagName, Pageable pageable) {
QueryResults<Post> results = queryFactory
.selectFrom(post)
.innerJoin(postTag)
.on(post.idx.eq(postTag.post.idx))
.innerJoin(tag)
.on(tag.idx.eq(postTag.tag.idx))
.where(tag.name.eq(tagName))
.orderBy(post.idx.desc())
.limit(pageable.getPageSize())
.offset(pageable.getOffset())
.fetchResults();
return new PageImpl<>(results.getResults(), pageable, results.getTotal());
}
프로젝트 개발 회고 글: