Skip to content

Article: Article, Draft 모듈 초기 세팅 #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 42 commits into
base: main
Choose a base branch
from
Open

Conversation

sweetykr7
Copy link

@sweetykr7 sweetykr7 commented May 6, 2025

Pull Request

Issues

Description

  • Post, Draft에 대한 모듈을 제작하였습니다. [MAIN] Post Domain 구현 #56

  • Draft Table(임시글)을 ERD에 추가하였습니다.(기존에는 임시글이 없었습니다)

    • 포스트와 비교하여 보면 조회수, 공유수, 좋아요수가 제외되었습니다.
    • 상태에서 DRAFT(임시), DONE(완료됨, 포스트 만들어진 상태), DELETED(삭제), PENDING(대기)를 만들었습니다.
  • Exception을 추가 하였습니다.

    • Post, Draft에 대한 Exception을 추가하였습니다. Board기반으로 작성되었습니다.
  • Read-model을 추가 하였습니다.

    • Post, Draft에 대한 Read-model을 추가하였습니다.
    • Draft는 갯수가 많지 않을 것으로 고려되어 마지막 조회 시간 이후로 가져오는 로직이 아니라, 전체를 가져오는 것으로 만들었습니다.
  • Adapter를 추가하였습니다.

    • Post, Draft에 대한 Driving, Driven Adapter를 추가하였습니다.
    • rdb adapter의 entity status에서는 generic type으로 컴파일 타임에 체크하게 하였습니다.
      • StatusParameters라는 class를 따로 두어서 이곳에서 체크하게 하였습니다.(기존 Hexagonal과 Enum Util에서 참고)
  • Service를 추가하였습니다.

    • Post, Draft에 대한 Command, Query Service를 추가하였습니다.

How Has This Been Tested?

  • Test는 추후 추가할 예정입니다.

Additional Notes

만들면서 발생된 문제들

  • user id를 고려하지 못한 것 같습니다.

    • user 단위로 가져오는 부분도 있을 것 같은데, 그렇지 않으면 모든 post를 긁어와야 해서 데이터 양이 상당해질 것 같습니다.
  • multi-module 관련

    • 특정 부분이 제대로 설정이 되지 않은 것 같습니다. 아래와 같은 에러가 발생합니다.
      Config data resource 'class path resource [post-web.yml]' via location 'post-web.yml' does not exist
    • 아래는 해결하기 위해서 시도했던 사항들입니다.
      • monolith main-runner의 build.gradle.kts에 post를 넣어두었습니다. implementation(project(":post"))
      • monolith main-runner의 resources의 application.yml에 post.yml를 추가하였습니다.
      • services/post/src/main/resources에 post.yml을 추가하였습니다.
      • 각 모듈 :post:webmvc-adapter:post:rdb-adapter의 src/main/resources에 해당하는 yml파일을 추가하였습니다.

@sweetykr7 sweetykr7 linked an issue May 6, 2025 that may be closed by this pull request
6 tasks
@merge-simpson merge-simpson changed the title Post - post,draft 모듈 추가 및 exception, adapter, service추가 Article: Article, Draft 모듈 추가 및 Exception, Adapter, Service 추가 May 13, 2025
@merge-simpson merge-simpson changed the title Article: Article, Draft 모듈 추가 및 Exception, Adapter, Service 추가 Article: Article, Draft 모듈 초기 세팅 May 13, 2025
Copy link

@seonghooni seonghooni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생 많으셨습니다!!
추가적인 리뷰 있으면 또 남기겠습니다!

Objects.requireNonNull(content, "Content cannot be null");
Objects.requireNonNull(status, "status cannot be null");
Objects.requireNonNull(totalLikes, "totalLikes cannot be null");
Objects.requireNonNull(totalLikes, "totalLikes cannot be null");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위 코드와 중복됩니다!
하나는 totalViews로 작성하려고 하셨던 거라고 생각됩니다!

var existArticle = articleJpaRepository.findById(article.getId())
.orElseThrow(ARTICLE_NOT_FOUND::exception);
existArticle.prepareArticleEntityUpdate()
.title(existArticle.getTitle())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

article.getTitle()
아닐까요?!

}

@Override
public Article create(Article article) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adapter (=Repository) 함수 네이밍은 save()가 더 적합하지 않나 생각됩니다!

create -> RDB 또는 usecase 관점
save -> JPA와 같은 ORM 관점 표준 네이밍 이라고 생각합니다.

다른 분들 의견도 한번 여쭤보고 싶습니다!

.totalShares(existArticle.getTotalShares())
.update();

return articleEntityMapper.toDomain(articleJpaRepository.save(existArticle));
Copy link

@seonghooni seonghooni May 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이미 영속상태인 엔티티(findById로 호출함)가 직접 수정되면,
영속성 컨텍스트에도 반영이 되기 때문에
articleEntityMapper.toDomain(existArticle);
처럼 실행해도 같은 결과를 얻을 수 있습니다!

단, 이 함수를 실행하는 영역에서 @Transactional 이 명시되어야 합니다.
지금 코드를 보니 CommandService에서는 트랜잭션이 적용되지 않은 것 같아요!

Comment on lines +16 to +23
@Override
public Article createArticle(Article article) {
return articleCommandPort.create(article);
}
@Override
public Article updateArticle(Article article) {
return articleCommandPort.update(article);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

함수와 함수 사이에는 공백 줄을 넣어 주시면 감사합니다!

Comment on lines +20 to +30
private final ArticleQueryPort articleQueryPort;
@Override
public Optional<ArticleDetail> getArticle(Long id) {
return articleQueryPort.findById(id);
}
@Override
public Page<ArticleSummary> getAllArticle(Instant lastCreatedAt, int size) {
return articleQueryPort.findAllAfter(lastCreatedAt, size);
}
@Override
public Page<ArticleSummary> findByStatuses(Set<ArticleStatus> statuses, Instant lastCreatedAt, int size) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 함수와 함수 사이에는 공백줄을 추가해 주시면 감사합니다!

Comment on lines +11 to +12
Optional<ArticleDetail> getArticle(Long id);
Page<ArticleSummary> getAllArticle(Instant lastCreatedAt, int size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인터페이스에 내에 정의된 함수 사이에도 함수에는 공백 줄을 추가해주시면 감사합니다!

ex)

public interface ArticleReadUseCase {

    Optional<ArticleDetail> getArticle(Long id);

    Page<ArticleSummary> getAllArticle(Instant lastCreatedAt, int size);
}

Comment on lines +15 to +25

@Getter
@DynamicUpdate
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity(name = "article")
public class ArticleEntity extends LongBaseTimeEntity {
public String title;
public String content;
public Integer totalViews = 0;
public Integer totalLikes = 0;
public Integer totalShares = 0;
Copy link
Contributor

@silberbullet silberbullet May 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 Enitity 변수의 접근제어자가 public으로 바뀌었네요! 👍

하기 애노테이션은 수정이 필요합니다! Drafts Enitity도 꼭 수정해 주세요.

  • @Getter : public으로 인하여 더 이상 Getter 없이도 변수 접근이 가능합니다.
  • @NoArgsConstructor(access = AccessLevel.PROTECTED): Entity 클래스는 기본적으로 기본 생성자를 필요로 하며, 접근제어 세부 설정을 제외해도 좋습니다. @NoArgsConstructor 로 수정하기

Comment on lines +9 to +10
// spring
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💊 Application은 의미론적으로 JPA 한정적이다 보다는 spring-data-commons 라이브러리로 그 의미를 명확하게 해주는게 좋을 것 같습니다.

ex)

    // spring
   implementation("org.springframework.data:spring-data-commons")

Copy link
Contributor

@silberbullet silberbullet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 공수가 큰 작업에 크게 수고하셨습니다!

로컬 실행 결과 동작에는 큰 문제가 없어서 🚀 Approve 입니다!

💊 다만 스타일과 문법적으로 몇 가지 통일성을 위해 추가 코멘트를 남깁니다!


@Builder
public record ArticleUpdateCommand(
@NotBlank(message = "id를 입력하십시오.")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long 타입은 @NotBlank가 아닌 @NotNull로 수정해주세요!

@NotBlank를 쓴다면 컴파일 에러는 발생하지 않더라도 유효성 검사가 정상적으로 이루어지지 않는 것으로 알고 있습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: article Issues in the article module review: ing Reviews are in progress and taking time type: feature 새로운 기능 또는 기능적 개선 A new feature or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SUB-ISSUE] Article: 모듈별 베이스 패키지 구분 [MAIN] Post Domain 구현
4 participants