diff --git a/core/jpa-core/src/main/java/nettee/jpa/support/LongBaseEntity.java b/core/jpa-core/src/main/java/nettee/jpa/support/LongBaseEntity.java index a714bd21..95c1cd69 100644 --- a/core/jpa-core/src/main/java/nettee/jpa/support/LongBaseEntity.java +++ b/core/jpa-core/src/main/java/nettee/jpa/support/LongBaseEntity.java @@ -7,8 +7,12 @@ import lombok.Getter; import java.io.Serializable; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; @Getter +@SuperBuilder +@NoArgsConstructor @MappedSuperclass public abstract class LongBaseEntity implements Serializable { @Id diff --git a/core/jpa-core/src/main/java/nettee/jpa/support/LongBaseTimeEntity.java b/core/jpa-core/src/main/java/nettee/jpa/support/LongBaseTimeEntity.java index d2a03e53..689c9798 100644 --- a/core/jpa-core/src/main/java/nettee/jpa/support/LongBaseTimeEntity.java +++ b/core/jpa-core/src/main/java/nettee/jpa/support/LongBaseTimeEntity.java @@ -3,6 +3,8 @@ import jakarta.persistence.EntityListeners; import jakarta.persistence.MappedSuperclass; import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -11,6 +13,8 @@ @Getter @MappedSuperclass +@SuperBuilder +@NoArgsConstructor @EntityListeners(AuditingEntityListener.class) public abstract class LongBaseTimeEntity extends LongBaseEntity { @CreatedDate diff --git a/monolith/main-runner/src/main/resources/db/migration/v1_0/V1_0_5__create_tb_comment.sql b/monolith/main-runner/src/main/resources/db/migration/v1_0/V1_0_5__create_tb_comment.sql index 5b4a493c..d0c3984a 100644 --- a/monolith/main-runner/src/main/resources/db/migration/v1_0/V1_0_5__create_tb_comment.sql +++ b/monolith/main-runner/src/main/resources/db/migration/v1_0/V1_0_5__create_tb_comment.sql @@ -1,10 +1,9 @@ CREATE TABLE IF NOT EXISTS article.comment ( id BIGSERIAL, board_id BIGINT, - content VARCHAR(255), - status INTEGER, + replies JSON, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP, @@ -18,5 +17,6 @@ COMMENT ON TABLE article.comment IS '댓글'; COMMENT ON COLUMN article.comment.content IS '내용'; COMMENT ON COLUMN article.comment.board_id IS '게시물 ID'; COMMENT ON COLUMN article.comment.status IS '상태'; +COMMENT ON COLUMN article.comment.replies IS '답글 목록'; COMMENT ON COLUMN article.comment.created_at IS '생성시간'; COMMENT ON COLUMN article.comment.updated_at IS '마지막 수정시간'; diff --git a/services/comment/api/domain/src/main/java/nettee/comment/domain/Comment.java b/services/comment/api/domain/src/main/java/nettee/comment/domain/Comment.java index 50547c3f..032bbacc 100644 --- a/services/comment/api/domain/src/main/java/nettee/comment/domain/Comment.java +++ b/services/comment/api/domain/src/main/java/nettee/comment/domain/Comment.java @@ -1,12 +1,15 @@ package nettee.comment.domain; import java.time.Instant; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import nettee.comment.domain.type.CommentStatus; +import nettee.reply.domain.Reply; @Getter @Builder @@ -26,6 +29,9 @@ public class Comment { private Instant updatedAt; + @Builder.Default + private List replies = new ArrayList<>(); + @Builder( builderClassName = "updateCommentBuilder", builderMethodName = "prepareUpdate", diff --git a/services/comment/application/src/main/java/nettee/comment/application/port/CommentCommandRepositoryPort.java b/services/comment/application/src/main/java/nettee/comment/application/port/CommentCommandRepositoryPort.java index f93c888f..692f4ab0 100644 --- a/services/comment/application/src/main/java/nettee/comment/application/port/CommentCommandRepositoryPort.java +++ b/services/comment/application/src/main/java/nettee/comment/application/port/CommentCommandRepositoryPort.java @@ -1,7 +1,9 @@ package nettee.comment.application.port; +import java.util.List; import nettee.comment.domain.Comment; import nettee.comment.domain.type.CommentStatus; +import nettee.reply.domain.Reply; public interface CommentCommandRepositoryPort { @@ -9,5 +11,9 @@ public interface CommentCommandRepositoryPort { Comment update(Comment comment); + Comment findById(Long id); + void updateStatus(Long id, CommentStatus status); + + void updateReplies(Long id, List replyList); } diff --git a/services/comment/application/src/main/java/nettee/comment/application/service/CommentQueryService.java b/services/comment/application/src/main/java/nettee/comment/application/service/CommentQueryService.java index c7b5f18d..078244b4 100644 --- a/services/comment/application/src/main/java/nettee/comment/application/service/CommentQueryService.java +++ b/services/comment/application/src/main/java/nettee/comment/application/service/CommentQueryService.java @@ -38,4 +38,7 @@ public List getCommentsByBoardId(Long boardId) { return result; } + public List getJsonByBoardId(Long boardId) { + return commentQueryRepositoryPort.findPageByBoardId(boardId, 0, 10); + } } diff --git a/services/comment/application/src/main/java/nettee/reply/application/port/ReplyCommandRepositoryPort.java b/services/comment/application/src/main/java/nettee/reply/application/port/ReplyCommandRepositoryPort.java index fea7b2e3..4baf50fc 100644 --- a/services/comment/application/src/main/java/nettee/reply/application/port/ReplyCommandRepositoryPort.java +++ b/services/comment/application/src/main/java/nettee/reply/application/port/ReplyCommandRepositoryPort.java @@ -1,5 +1,6 @@ package nettee.reply.application.port; +import java.time.Instant; import nettee.reply.domain.Reply; import nettee.reply.domain.type.ReplyStatus; @@ -9,5 +10,9 @@ public interface ReplyCommandRepositoryPort { Reply update(Reply reply); + Reply findById(Long id); + void updateStatus(Long id, ReplyStatus status); + + Reply findFirstByCommentIdAfter(Long commentId, Instant createdAt); } diff --git a/services/comment/application/src/main/java/nettee/reply/application/service/ReplyCommandService.java b/services/comment/application/src/main/java/nettee/reply/application/service/ReplyCommandService.java index e53309f6..38f36b99 100644 --- a/services/comment/application/src/main/java/nettee/reply/application/service/ReplyCommandService.java +++ b/services/comment/application/src/main/java/nettee/reply/application/service/ReplyCommandService.java @@ -1,7 +1,10 @@ package nettee.reply.application.service; import jakarta.transaction.Transactional; +import java.util.List; +import java.util.Objects; import lombok.RequiredArgsConstructor; +import nettee.comment.application.port.CommentCommandRepositoryPort; import nettee.reply.domain.Reply; import nettee.reply.application.port.ReplyCommandRepositoryPort; import nettee.reply.domain.type.ReplyStatus; @@ -16,19 +19,77 @@ public class ReplyCommandService implements ReplyCreateUseCase, ReplyUpdateUseCase, ReplyDeleteUseCase { private final ReplyCommandRepositoryPort replyCommandRepositoryPort; + private final CommentCommandRepositoryPort commentCommandRepositoryPort; @Override public Reply createReply(Reply reply) { - return replyCommandRepositoryPort.save(reply); + var saveReply = replyCommandRepositoryPort.save(reply); + var comment = commentCommandRepositoryPort.findById(reply.getCommentId()); + + List replies = comment.getReplies(); + + // 답글의 개수가 10 미만이면, 해당 comment.replies에 reply를 추가합니다. + if(replies.size() < 10) { + replies.add(saveReply); + commentCommandRepositoryPort.updateReplies(comment.getId(), replies); + } + + return saveReply; } @Override public void deleteReply(Long id) { + var reply = replyCommandRepositoryPort.findById(id); + var comment = commentCommandRepositoryPort.findById(reply.getCommentId()); + + var replies = comment.getReplies(); + + // 1. comment.replies에 지우고자 하는 reply가 존재할 경우, comment도 업데이트 해야합니다. + // 1-1) comment.replies에 지우고자 하는 reply가 존재하는지 확인합니다. + boolean removed = replies.removeIf(r -> r.getId().equals(reply.getId())); + + // 1-2) 지우고자 하는 reply가 있었다면 + if(removed) { + + // 1-3) comment.replies의 크기가 10미만이 되었으므로 다음 reply가 더 있는지 확인 + var nextReply = replyCommandRepositoryPort.findFirstByCommentIdAfter( + comment.getId(), replies.getLast().getCreatedAt()); + + // 1-4) 다음 reply가 존재한다면 comment.replies에 추가해줍니다. + if(nextReply != null) { + replies.add(nextReply); + } + // 1-5) comment.replies에 변화가 있었으므로 업데이트합니다. + commentCommandRepositoryPort.updateReplies(comment.getId(),replies); + } + + // 2. reply의 status를 REMOVE로 설정합니다. replyCommandRepositoryPort.updateStatus(id, ReplyStatus.REMOVED); } @Override public Reply updateReply(Reply reply) { - return replyCommandRepositoryPort.update(reply); + var updateReply = replyCommandRepositoryPort.update(reply); + var comment = commentCommandRepositoryPort.findById(updateReply.getCommentId()); + + List replies = comment.getReplies(); + + // 1. comment.replies에 동일한 reply가 존재할 경우, comment도 업데이트 해야합니다. + // 1-1) comment.replies에 동일한 reply가 존재하는지 확인합니다. + boolean updated = false; + for(int i = 0; i < replies.size(); i++) { + if(Objects.equals(replies.get(i).getId(), reply.getId())) { + replies.set(i, updateReply); + updated = true; + break; + } + } + + // 1-2) 존재한다면, comment 역시 업데이트 해야합니다. + if(updated) { + commentCommandRepositoryPort.updateReplies(comment.getId(),replies); + } + + return updateReply; } } diff --git a/services/comment/driven/rdb/build.gradle.kts b/services/comment/driven/rdb/build.gradle.kts index e6322c82..67a4cf5a 100644 --- a/services/comment/driven/rdb/build.gradle.kts +++ b/services/comment/driven/rdb/build.gradle.kts @@ -5,6 +5,9 @@ dependencies { api(project(":comment:comment-application")) api(project(":jpa-core")) + // for using json column + implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") + implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") // querydsl implementation("com.querydsl:querydsl-jpa:${bom["querydsl.version"]}:jakarta") diff --git a/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/entity/CommentEntity.java b/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/entity/CommentEntity.java index 631a3c8f..fef4bdc8 100644 --- a/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/entity/CommentEntity.java +++ b/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/entity/CommentEntity.java @@ -3,16 +3,25 @@ import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Entity; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import lombok.AccessLevel; import lombok.Builder; import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; import nettee.comment.driven.rdb.entity.type.CommentEntityStatus; import nettee.comment.driven.rdb.entity.type.CommentEntityStatusConverter; +import nettee.comment.driven.rdb.entity.type.ReplyListConverter; import nettee.jpa.support.LongBaseTimeEntity; +import nettee.reply.driven.rdb.entity.ReplyEntity; import org.hibernate.annotations.DynamicUpdate; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; @DynamicUpdate +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@SuperBuilder @Entity(name = "comment") public class CommentEntity extends LongBaseTimeEntity { @@ -24,11 +33,16 @@ public class CommentEntity extends LongBaseTimeEntity { @Convert(converter = CommentEntityStatusConverter.class) public CommentEntityStatus status; + @Convert(converter = ReplyListConverter.class) + @JdbcTypeCode(SqlTypes.JSON) + public List replies = new ArrayList<>(); + @Builder - public CommentEntity(Long boardId, String content, CommentEntityStatus status) { + public CommentEntity(Long boardId, String content, CommentEntityStatus status, List replies) { this.boardId = boardId; this.content = content; this.status = status; + this.replies = replies; } @Builder( @@ -52,4 +66,15 @@ public void updateStatus(CommentEntityStatus status) { this.status = status; } + + @Builder( + builderClassName = "updateReplyListBuilder", + builderMethodName = "prepareReplyListUpdate", + buildMethodName = "updateReplyList" + ) + public void updateReplyList(List replies) { + Objects.requireNonNull(replies, "replies cannot be null"); + + this.replies = replies; + } } diff --git a/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/entity/type/ReplyListConverter.java b/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/entity/type/ReplyListConverter.java new file mode 100644 index 00000000..846adde6 --- /dev/null +++ b/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/entity/type/ReplyListConverter.java @@ -0,0 +1,41 @@ +package nettee.comment.driven.rdb.entity.type; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; +import java.util.ArrayList; +import java.util.List; +import nettee.reply.driven.rdb.entity.ReplyEntity; + +import static nettee.comment.exception.CommentCommandErrorCode.DEFAULT; + +@Converter +public class ReplyListConverter implements AttributeConverter, String> { + + private final ObjectMapper objectMapper = new ObjectMapper() + .registerModule(new JavaTimeModule()) + .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // 날짜 필드를 숫자가 아닌 ISO 8601 문자열("2025-06-06T04:37:00Z")로 직렬화합니다. + + @Override + public String convertToDatabaseColumn(List replies) { + try { + return objectMapper.writeValueAsString(replies); + } catch (JsonProcessingException e) { + throw DEFAULT.exception(); + } + } + + @Override + public List convertToEntityAttribute(String dbData) { + try { + if (dbData == null || dbData.isBlank()) return new ArrayList<>(); + return objectMapper.readValue(dbData, new TypeReference>() {}); + } catch (JsonProcessingException e) { + throw DEFAULT.exception(); + } + } +} diff --git a/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/persistence/CommentCommandAdapter.java b/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/persistence/CommentCommandAdapter.java index 3ef58d90..a6414232 100644 --- a/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/persistence/CommentCommandAdapter.java +++ b/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/persistence/CommentCommandAdapter.java @@ -1,11 +1,14 @@ package nettee.comment.driven.rdb.persistence; +import java.util.List; import lombok.RequiredArgsConstructor; import nettee.comment.domain.Comment; import nettee.comment.driven.rdb.entity.type.CommentEntityStatus; import nettee.comment.driven.rdb.persistence.mapper.CommentEntityMapper; import nettee.comment.application.port.CommentCommandRepositoryPort; import nettee.comment.domain.type.CommentStatus; +import nettee.reply.domain.Reply; +import nettee.reply.driven.rdb.persistence.mapper.ReplyEntityMapper; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Repository; @@ -18,6 +21,7 @@ public class CommentCommandAdapter implements CommentCommandRepositoryPort { private final CommentJpaRepository commentJpaRepository; private final CommentEntityMapper commentEntityMapper; + private final ReplyEntityMapper replyEntityMapper; @Override public Comment save(Comment comment) { @@ -43,6 +47,14 @@ public Comment update(Comment comment) { return commentEntityMapper.toDomain(existComment); } + @Override + public Comment findById(Long id) { + var commentEntity = commentJpaRepository.findById(id) + .orElseThrow(COMMENT_NOT_FOUND::exception); + + return commentEntityMapper.toDomain(commentEntity); + } + @Override public void updateStatus(Long id, CommentStatus status) { var existComment = commentJpaRepository.findById(id) @@ -52,4 +64,16 @@ public void updateStatus(Long id, CommentStatus status) { .status(CommentEntityStatus.valueOf(status)) .updateStatus(); } + + @Override + public void updateReplies(Long id, List replyList) { + var existComment = commentJpaRepository.findById(id) + .orElseThrow(COMMENT_NOT_FOUND::exception); + + var replies = replyEntityMapper.toEntityList(replyList); + + existComment.prepareReplyListUpdate() + .replies(replies) + .updateReplyList(); + } } diff --git a/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/persistence/mapper/CommentEntityMapper.java b/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/persistence/mapper/CommentEntityMapper.java index 1fb613e6..0a0dcdd4 100644 --- a/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/persistence/mapper/CommentEntityMapper.java +++ b/services/comment/driven/rdb/src/main/java/nettee/comment/driven/rdb/persistence/mapper/CommentEntityMapper.java @@ -4,9 +4,10 @@ import nettee.comment.domain.Comment; import nettee.comment.driven.rdb.entity.CommentEntity; import nettee.comment.model.CommentQueryModels.CommentDetail; +import nettee.reply.driven.rdb.persistence.mapper.ReplyEntityMapper; import org.mapstruct.Mapper; -@Mapper(componentModel = "spring") +@Mapper(componentModel = "spring", uses = ReplyEntityMapper.class) public interface CommentEntityMapper { Comment toDomain(CommentEntity commentEntity); diff --git a/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/entity/ReplyEntity.java b/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/entity/ReplyEntity.java index 054a149b..3ea53424 100644 --- a/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/entity/ReplyEntity.java +++ b/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/entity/ReplyEntity.java @@ -4,15 +4,17 @@ import jakarta.persistence.Convert; import jakarta.persistence.Entity; import java.util.Objects; -import lombok.AccessLevel; import lombok.Builder; import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; import nettee.jpa.support.LongBaseTimeEntity; import nettee.reply.driven.rdb.entity.type.ReplyEntityStatus; import nettee.reply.driven.rdb.entity.type.ReplyEntityStatusConverter; import org.hibernate.annotations.DynamicUpdate; @DynamicUpdate +@NoArgsConstructor +@SuperBuilder @Entity(name = "reply") public class ReplyEntity extends LongBaseTimeEntity { diff --git a/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/ReplyCommandAdapter.java b/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/ReplyCommandAdapter.java index bf0acb7e..beedce8b 100644 --- a/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/ReplyCommandAdapter.java +++ b/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/ReplyCommandAdapter.java @@ -1,5 +1,6 @@ package nettee.reply.driven.rdb.persistence; +import java.time.Instant; import lombok.RequiredArgsConstructor; import nettee.reply.domain.Reply; import nettee.reply.driven.rdb.entity.type.ReplyEntityStatus; @@ -7,6 +8,8 @@ import nettee.reply.application.port.ReplyCommandRepositoryPort; import nettee.reply.domain.type.ReplyStatus; import org.springframework.dao.DataAccessException; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; import static nettee.reply.exception.ReplyCommandErrorCode.DEFAULT; @@ -43,6 +46,14 @@ public Reply update(Reply reply) { return replyEntityMapper.toDomain(existReply); } + @Override + public Reply findById(Long id) { + var replyEntity = replyJpaRepository.findById(id) + .orElseThrow(REPLY_NOT_FOUND::exception); + + return replyEntityMapper.toDomain(replyEntity); + } + @Override public void updateStatus(Long id, ReplyStatus status) { var existReply = replyJpaRepository.findById(id) @@ -52,4 +63,12 @@ public void updateStatus(Long id, ReplyStatus status) { .status(ReplyEntityStatus.valueOf(status)) .updateStatus(); } + + @Override + public Reply findFirstByCommentIdAfter(Long commentId, Instant createdAt) { + var replyEntity = replyJpaRepository.findByCommentIdAndCreatedAtAfter(commentId, createdAt, ReplyEntityStatus.ACTIVE, + PageRequest.of(0,1)); + + return replyEntityMapper.toDomain(replyEntity.get(0)); + } } diff --git a/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/ReplyJpaRepository.java b/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/ReplyJpaRepository.java index c3d00549..95a5c383 100644 --- a/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/ReplyJpaRepository.java +++ b/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/ReplyJpaRepository.java @@ -1,8 +1,19 @@ package nettee.reply.driven.rdb.persistence; - +import java.time.Instant; +import java.util.List; +import java.util.Optional; import nettee.reply.driven.rdb.entity.ReplyEntity; +import nettee.reply.driven.rdb.entity.type.ReplyEntityStatus; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface ReplyJpaRepository extends JpaRepository { - + @Query("SELECT r FROM reply r WHERE r.commentId = :commentId AND r.createdAt > :createdAt AND r.status =:status ORDER BY r.createdAt") + List findByCommentIdAndCreatedAtAfter( + @Param("commentId") Long commentId, + @Param("createdAt") Instant createdAt, + @Param("status") ReplyEntityStatus status, + Pageable pageable); } diff --git a/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/mapper/ReplyEntityMapper.java b/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/mapper/ReplyEntityMapper.java index c82ec04c..465dc58b 100644 --- a/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/mapper/ReplyEntityMapper.java +++ b/services/comment/driven/rdb/src/main/java/nettee/reply/driven/rdb/persistence/mapper/ReplyEntityMapper.java @@ -1,5 +1,6 @@ package nettee.reply.driven.rdb.persistence.mapper; +import java.util.List; import java.util.Optional; import nettee.reply.domain.Reply; import nettee.reply.driven.rdb.entity.ReplyEntity; @@ -15,6 +16,10 @@ public interface ReplyEntityMapper { ReplyEntity toEntity(Reply reply); + List toEntityList(List replies); + + List toDomainList(List replyEntities); + default Optional toOptionalReplyDetail(ReplyEntity replyEntity) { return Optional.ofNullable(toReplyDetail(replyEntity)); } diff --git a/services/comment/driving/web-mvc/src/main/java/nettee/comment/web/CommentQueryApi.java b/services/comment/driving/web-mvc/src/main/java/nettee/comment/web/CommentQueryApi.java index cacd2244..7b612ea9 100644 --- a/services/comment/driving/web-mvc/src/main/java/nettee/comment/web/CommentQueryApi.java +++ b/services/comment/driving/web-mvc/src/main/java/nettee/comment/web/CommentQueryApi.java @@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -16,9 +17,14 @@ public class CommentQueryApi { private final CommentQueryService commentQueryService; - @GetMapping("/{boardId}") - public List getCommentsByBoardId(@PathVariable("boardId") Long boardId) { + @GetMapping() + public List getCommentsByBoardId(@RequestParam("boardId") Long boardId) { return commentQueryService.getCommentsByBoardId(boardId); } + @GetMapping("/json") + public List getJsonByBoardId(@RequestParam("boardId") Long boardId) { + return commentQueryService.getJsonByBoardId(boardId); + } + }