Skip to content

Commit 0dfc472

Browse files
committed
v1.0.2 (#105)
* refactor: 클린 코드를 위한 리팩터링 (#101) * style: 안 쓰는 파라미터 및 코드 제거 * refactor: findById로 변경 * refactor: 첫 번째 사진 가져오는 기능 추상화 * chore: readme 작성 (#104) * chore: readme 초안 작성 * chore: 설계 이미지 추가 * chore: readme 사용 기술 세분화 * chore: 순서 변경
1 parent fae6d01 commit 0dfc472

File tree

7 files changed

+105
-19
lines changed

7 files changed

+105
-19
lines changed

README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,91 @@
11
# sns
2+
3+
## 📌 개요
4+
5+
Instagram과 유사한 간단한 SNS 서비스 백엔드 구현<br>
6+
도메인 주소: https://wlsh-sns.duckdns.org/ <br>
7+
8+
## 📌 프로젝트 중점 사항
9+
10+
- SNS 서비스 설계 및 구현
11+
- JPA 활용과 N + 1 문제 경험 및 쿼리 튜닝을 통한 해결
12+
- Junit을 이용하여 높은 커버리지의 단위 테스트 작성을 통해 리팩터링 등의 과정에도 코드의 신뢰성 경험
13+
- CI/CD를 적용하여 자동화 된 빌드와 무중단 배포 경험
14+
- 성능 테스트을 경험하고, 개선을 통한 차이 확인
15+
- 캐싱을 적용하여 과부화가 걸릴 것이라 판단되는 시나리오의 성능 개선(진행 중)
16+
17+
## 📌 사용 기술
18+
19+
**Idea**
20+
21+
![idea](https://img.shields.io/badge/IntelliJ-grey)
22+
23+
**Development**
24+
25+
![java](https://img.shields.io/badge/open--jdk-17-brightgreen)
26+
[![framework](https://img.shields.io/badge/spring%20boot-2.7.8-yellowgreen)](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.7-Release-Notes)
27+
[![build tool](https://img.shields.io/badge/gradle-7.6-orange)](https://gradle.org/)
28+
![ORM](https://img.shields.io/badge/JPA-grey)
29+
[![Rdb](https://img.shields.io/badge/MySQL-8.0-blue)](https://dev.mysql.com/doc/refman/8.0/en/)
30+
31+
**Deploy**
32+
33+
![cloud](https://img.shields.io/badge/Naver%20Cloud%20Platform-grey)
34+
![OS](https://img.shields.io/badge/ubuntu-18.04-red)
35+
![CI CD](https://img.shields.io/badge/Github%20Actions-grey)
36+
[![image](https://img.shields.io/badge/docker-latest-lightgrey)](https://hub.docker.com/r/k87913j/sns)
37+
38+
**Test**
39+
40+
[![Rdb](https://img.shields.io/badge/JUnit-5.0-yellow)](https://junit.org/junit5/)
41+
[![Rdb](https://img.shields.io/badge/mockito-5.3-yellowgreen)](https://site.mockito.org/)
42+
43+
44+
**Load Test**
45+
46+
![load test](https://img.shields.io/badge/ngrinder-3.5-green)
47+
48+
49+
## 📌 주요 기능
50+
51+
- 인증 및 인가 기능
52+
- 게시글 기능
53+
- 댓글 기능
54+
- 팔로우 기능
55+
- 좋아요 기능
56+
- 알람 기능
57+
- 피드 기능
58+
59+
## 📌 아키텍쳐
60+
61+
<img width="873" alt="image" src="https://github.com/wlsh44/sns/assets/49276666/a496bb73-b8ce-4bee-b399-354ed67d6302">
62+
63+
64+
## 📌 브랜치 및 커밋 전략
65+
66+
**Pull Request**
67+
68+
- PR 전략
69+
- Squash and Merge
70+
- PR 커밋 메시지
71+
- Default to pull request title and commit details
72+
- develop, main 브랜치 커밋의 수를 줄여, 전체적인 개발 흐름의 파악을 위함
73+
74+
**Commit Convention**
75+
76+
- \<type>: \<body>
77+
- type
78+
- feat: 새로운 기능 추가
79+
- modify: API 변경 등의 기능 변경
80+
- refactor: 코드 리팩터링
81+
- fix: 버그 수정
82+
- chore: 코드 외의 작업
83+
- style: 코드 포맷팅 및 정리
84+
- test: 테스트 관련 코드 변경 및 추가
85+
86+
**Branch**
87+
88+
- main: 배포를 위한 브랜치
89+
- develop: 다음 버전 개발을 위한 브랜치
90+
- 이 외의 브랜치는 브랜치의 개발 기능을 중점으로 커밋 컨벤션의 type과 유사하게 함
91+
- feature 브랜치를 제외하고 type/issue번호 의 이름 전략을 사용함
Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package com.example.sns.post.application;
22

3-
import com.example.sns.member.domain.Member;
4-
import com.example.sns.member.domain.MemberRepository;
5-
import com.example.sns.member.exception.MemberNotFoundException;
6-
import com.example.sns.post.domain.Feed;
73
import com.example.sns.post.domain.LikeRepository;
84
import com.example.sns.post.domain.Post;
95
import com.example.sns.post.domain.PostRepository;
@@ -24,32 +20,29 @@
2420
@RequiredArgsConstructor
2521
public class FeedService {
2622

27-
private final MemberRepository memberRepository;
2823
private final PostRepository postRepository;
2924
private final LikeRepository likeRepository;
3025

3126
public MyFeedResponse findMyFeed(Long memberId, Pageable pageable) {
32-
Member member = getMember(memberId);
3327
Slice<Post> myFeedSlice = postRepository.findMyFeed(memberId, pageable);
3428

35-
List<PostResponse> postResponses = getPostResponses(memberId, member, myFeedSlice);
29+
List<PostResponse> postResponses = getPostResponses(memberId, myFeedSlice);
3630
return MyFeedResponse.from(postResponses, myFeedSlice.hasNext(), myFeedSlice.getNumber());
3731
}
3832

39-
private List<PostResponse> getPostResponses(Long memberId, Member member, Slice<Post> myFeedSlice) {
33+
private List<PostResponse> getPostResponses(Long memberId, Slice<Post> myFeedSlice) {
4034
return myFeedSlice.getContent().stream()
41-
.map(post -> PostResponse.from(post, member, likeRepository.existsByMemberIdAndPostId(memberId, post.getId())))
35+
.map(post -> PostResponse.from(post, isMemberLikePost(memberId, post)))
4236
.collect(Collectors.toList());
4337
}
4438

39+
private boolean isMemberLikePost(Long memberId, Post post) {
40+
return likeRepository.existsByMemberIdAndPostId(memberId, post.getId());
41+
}
42+
4543
public RecentFeedResponse findRecentFeed(Pageable pageable) {
4644
Slice<Post> recentFeedSlice = postRepository.findRecentFeed(pageable);
4745

4846
return RecentFeedResponse.from(recentFeedSlice.getContent(), recentFeedSlice.hasNext(), recentFeedSlice.getNumber());
4947
}
50-
51-
private Member getMember(Long memberId) {
52-
return memberRepository.findById(memberId)
53-
.orElseThrow(() -> new MemberNotFoundException(memberId));
54-
}
5548
}

src/main/java/com/example/sns/post/application/PostQueryService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public PostResponse findPost(Long memberId, Long postId) {
2626
Post post = getPost(postId);
2727

2828
boolean like = likeRepository.existsByMemberIdAndPostId(memberId, postId);
29-
return PostResponse.from(post, member, like);
29+
return PostResponse.from(post, like);
3030
}
3131

3232
private Member getMember(Long memberId) {

src/main/java/com/example/sns/post/domain/Post.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,8 @@ public void validateIsAuthor(Long memberId) {
9494
throw new NotPostAuthorException();
9595
}
9696
}
97+
98+
public String getThumbnailImagePath() {
99+
return images.get(0).getImagePath();
100+
}
97101
}

src/main/java/com/example/sns/post/presentiation/dto/PostResponse.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.example.sns.post.presentiation.dto;
22

3-
import com.example.sns.member.domain.Member;
43
import com.example.sns.post.domain.Author;
54
import com.example.sns.post.domain.Post;
65
import com.example.sns.post.domain.PostImage;
@@ -30,7 +29,7 @@ public class PostResponse {
3029
@JsonProperty(namespace = "isLike")
3130
private final boolean like;
3231

33-
public static PostResponse from(Post post, Member member, boolean like) {
32+
public static PostResponse from(Post post, boolean like) {
3433
Author author = post.getAuthor();
3534
return new PostResponse(
3635
post.getId(),

src/main/java/com/example/sns/post/presentiation/dto/RecentFeedResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class RecentFeedResponse {
1616

1717
public static RecentFeedResponse from(List<Post> posts, boolean hasNext, int offset) {
1818
List<RecentFeedPostResponse> timeline = posts.stream()
19-
.map(post -> new RecentFeedPostResponse(post.getId(), post.getImages().get(0).getImagePath()))
19+
.map(post -> new RecentFeedPostResponse(post.getId(), post.getThumbnailImagePath()))
2020
.toList();
2121
return new RecentFeedResponse(timeline, !hasNext, offset);
2222
}

src/main/resources/scripts/sql/ddl.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ CREATE TABLE `post` (
2626
`id` bigint NOT NULL AUTO_INCREMENT,
2727
`created_at` datetime NOT NULL,
2828
`last_modified_at` datetime NOT NULL,
29-
`content` varchar(255) NOT NULL DEFAULT '',
29+
`content` text NOT NULL DEFAULT (''),
3030
`member_id` bigint NOT NULL,
3131
PRIMARY KEY (`id`),
3232
KEY `FK83s99f4kx8oiqm3ro0sasmpww` (`member_id`),

0 commit comments

Comments
 (0)