diff --git a/src/main/java/daybyquest/post/application/GetPostService.java b/src/main/java/daybyquest/post/application/GetPostService.java new file mode 100644 index 0000000..a6654f3 --- /dev/null +++ b/src/main/java/daybyquest/post/application/GetPostService.java @@ -0,0 +1,29 @@ +package daybyquest.post.application; + +import daybyquest.post.dto.response.PostResponse; +import daybyquest.post.query.PostDao; +import daybyquest.post.query.PostData; +import daybyquest.user.query.Profile; +import daybyquest.user.query.ProfileDao; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class GetPostService { + + private final PostDao postDao; + + private final ProfileDao profileDao; + + public GetPostService(final PostDao postDao, final ProfileDao profileDao) { + this.postDao = postDao; + this.profileDao = profileDao; + } + + @Transactional(readOnly = true) + public PostResponse invoke(final Long loginId, final Long postId) { + final PostData postData = postDao.getByPostId(loginId, postId); + final Profile profile = profileDao.getById(loginId, postData.getUserId()); + return PostResponse.of(postData, profile); + } +} diff --git a/src/main/java/daybyquest/post/dto/response/PostResponse.java b/src/main/java/daybyquest/post/dto/response/PostResponse.java new file mode 100644 index 0000000..3eb0042 --- /dev/null +++ b/src/main/java/daybyquest/post/dto/response/PostResponse.java @@ -0,0 +1,45 @@ +package daybyquest.post.dto.response; + +import daybyquest.image.vo.Image; +import daybyquest.post.query.PostData; +import daybyquest.user.dto.response.ProfileResponse; +import daybyquest.user.query.Profile; +import java.time.LocalDateTime; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class PostResponse { + + private ProfileResponse author; + + private Long id; + + private String content; + + private LocalDateTime updatedAt; + + private boolean liked; + + private List images; + + public PostResponse(final ProfileResponse author, final Long id, final String content, + final LocalDateTime updatedAt, final boolean liked, + final List images) { + this.author = author; + this.id = id; + this.content = content; + this.updatedAt = updatedAt; + this.liked = liked; + this.images = images; + } + + public static PostResponse of(final PostData postData, final Profile profile) { + return new PostResponse(ProfileResponse.of(profile), postData.getId(), postData.getContent(), + postData.getUpdatedAt(), postData.isLiked(), + postData.getImages().stream().map(Image::getImageIdentifier).toList() + ); + } +} diff --git a/src/main/java/daybyquest/post/presentation/PostQueryApi.java b/src/main/java/daybyquest/post/presentation/PostQueryApi.java new file mode 100644 index 0000000..7b8e203 --- /dev/null +++ b/src/main/java/daybyquest/post/presentation/PostQueryApi.java @@ -0,0 +1,27 @@ +package daybyquest.post.presentation; + +import daybyquest.auth.Authorization; +import daybyquest.auth.UserId; +import daybyquest.post.application.GetPostService; +import daybyquest.post.dto.response.PostResponse; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PostQueryApi { + + private final GetPostService getPostService; + + public PostQueryApi(final GetPostService getPostService) { + this.getPostService = getPostService; + } + + @GetMapping("/post/{postId}") + @Authorization + public ResponseEntity getPost(@UserId final Long loginId, @PathVariable final Long postId) { + final PostResponse response = getPostService.invoke(loginId, postId); + return ResponseEntity.ok(response); + } +} diff --git a/src/main/java/daybyquest/post/query/PostDao.java b/src/main/java/daybyquest/post/query/PostDao.java new file mode 100644 index 0000000..8113ea8 --- /dev/null +++ b/src/main/java/daybyquest/post/query/PostDao.java @@ -0,0 +1,6 @@ +package daybyquest.post.query; + +public interface PostDao { + + PostData getByPostId(final Long userId, final Long postId); +} diff --git a/src/main/java/daybyquest/post/query/PostDaoQuerydslImpl.java b/src/main/java/daybyquest/post/query/PostDaoQuerydslImpl.java new file mode 100644 index 0000000..101a561 --- /dev/null +++ b/src/main/java/daybyquest/post/query/PostDaoQuerydslImpl.java @@ -0,0 +1,48 @@ +package daybyquest.post.query; + +import static daybyquest.image.vo.QImage.image; +import static daybyquest.like.domain.QPostLike.postLike; +import static daybyquest.post.domain.QPost.post; + +import com.querydsl.core.types.Projections; +import com.querydsl.jpa.JPAExpressions; +import com.querydsl.jpa.impl.JPAQueryFactory; +import daybyquest.global.error.exception.NotExistPostException; +import daybyquest.image.vo.Image; +import java.util.List; +import org.springframework.stereotype.Repository; + +@Repository +public class PostDaoQuerydslImpl implements PostDao { + + private final JPAQueryFactory factory; + + public PostDaoQuerydslImpl(final JPAQueryFactory factory) { + this.factory = factory; + } + + @Override + public PostData getByPostId(final Long userId, final Long postId) { + final PostData postData = factory.select(Projections.constructor(PostData.class, + post.userId, + post.id, + post.content, + post.updatedAt, + JPAExpressions.selectFrom(postLike) + .where(postLike.userId.eq(userId).and(postLike.postId.eq(postId))) + .exists())) + .from(post) + .where(post.id.eq(postId)) + .fetchOne(); + if (postData == null) { + throw new NotExistPostException(); + } + final List images = factory.select(image) + .from(post) + .leftJoin(post.images, image) + .where(post.id.eq(postId)) + .fetch(); + postData.setImages(images); + return postData; + } +} diff --git a/src/main/java/daybyquest/post/query/PostData.java b/src/main/java/daybyquest/post/query/PostData.java new file mode 100644 index 0000000..8418b59 --- /dev/null +++ b/src/main/java/daybyquest/post/query/PostData.java @@ -0,0 +1,35 @@ +package daybyquest.post.query; + +import daybyquest.image.vo.Image; +import java.time.LocalDateTime; +import java.util.List; +import lombok.Getter; + +@Getter +public class PostData { + + private final Long userId; + + private final Long id; + + private final String content; + + private final LocalDateTime updatedAt; + + private final boolean liked; + + private List images; + + public PostData(final Long userId, final Long id, final String content, final LocalDateTime updatedAt, + final boolean liked) { + this.userId = userId; + this.id = id; + this.content = content; + this.updatedAt = updatedAt; + this.liked = liked; + } + + public void setImages(final List images) { + this.images = images; + } +}