[3주차] 정대교/[feat] 게시글 도메인 API 구현#113
Hidden character warning
[3주차] 정대교/[feat] 게시글 도메인 API 구현#113daekyochung wants to merge 2 commits intoLeets-Official:정대교/mainfrom
Conversation
- Post Entity nullable 설정 수정 - PostListResponse null 처리 추가 - API 테스트 완료 (POST, GET, PUT, DELETE)
|
상황 별로 예외 처리 파일을 세분화 한 이 인상 깊습니다! 예외 처리를 하나로 묶어서 관리하는 것이 편하다고 생각했는데, 이렇게 나누어 관리하니 의도가 명확하게 다가오고 오류가 발생할 때 유지 보수에도 좋을 것 같습니다. |
theSnackOverflow
left a comment
There was a problem hiding this comment.
커스텀 예외 클래스를 PostNotFoundException, ForbiddenException 등 타입별로 분리하고 GlobalExceptionHandler에서 각각 처리하는 구조가 깔끔하게 잡혀있네요. 생성 시 201 Created, 삭제 시 204 No Content 등 HTTP 상태 코드도 의미에 맞게 잘 반환해주셨습니다.
몇 가지 확인해보시면 좋을 것 같은 부분 남겨봅니다!
| public class PostListResponse { | ||
|
|
||
| private List<Long> postId; | ||
| private List<String> title; |
There was a problem hiding this comment.
응답 DTO가 컬럼별로 List<Long> postId, List<String> title처럼 구성되어 있는데요, 이 구조는 게시글 하나를 표현하는 단위가 없어서 클라이언트가 인덱스로 각 필드를 조합해야 합니다. 일반적으로는 게시글 하나를 나타내는 inner DTO를 만들고 List<PostSummary> 형태로 감싸는 구조를 사용해요!
@Getter
@AllArgsConstructor
public class PostListResponse {
private List<PostSummary> posts;
@Getter
@Builder
public static class PostSummary {
private Long postId;
private String title;
private String nickname;
private LocalDateTime createdAt;
}
}| @Getter | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @Setter | ||
| @NoArgsConstructor |
There was a problem hiding this comment.
엔티티에 @Setter가 추가됐는데요, 이렇게 하면 서비스나 컨트롤러 어느 곳에서든 post.setTitle(...) 형태로 필드를 직접 변경할 수 있어서, 데이터가 어디서 바뀌는지 추적하기 어려워집니다. JPA 엔티티는 변경이 필요한 경우 의미 있는 이름의 메서드(예: post.update(title, content))를 정의하고, @Setter는 제거하는 패턴을 권장해요!
@NoArgsConstructor(access = AccessLevel.PROTECTED)도 무분별한 new Post() 생성을 막아주는 좋은 패턴이라, 원래대로 되돌려주시면 좋을 것 같아요.
| private Long id; | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "user_id", nullable = false) |
There was a problem hiding this comment.
user_id를 nullable = true로 변경하셨는데, 혹시 의도하신 건가요? 게시글에 작성자 정보가 없어도 되는 구조라면 맞지만, 대부분의 경우 게시글은 반드시 작성자가 있어야 하므로 nullable = false가 더 적절할 것 같아요.
| */ | ||
| @PostMapping | ||
| public ResponseEntity<PostResponse> createPost(@RequestBody PostCreateRequest request) { | ||
| PostResponse response = postService.createPost(request); |
There was a problem hiding this comment.
@RequestBody 앞에 @Valid가 빠져 있어서 PostCreateRequest의 @NotBlank 검증이 실제로 동작하지 않는 상태예요. @Valid를 추가해주시면 GlobalExceptionHandler의 MethodArgumentNotValidException 처리와 바로 연결됩니다!
public ResponseEntity<PostResponse> createPost(@RequestBody @Valid PostCreateRequest request)updatePost의 @RequestBody에도 동일하게 적용해주시면 좋을 것 같아요.
| .orElseThrow(() -> new PostNotFoundException(postId)); | ||
| post.increaseViewCount(); | ||
| postRepository.save(post); | ||
| return PostResponse.from(post); |
There was a problem hiding this comment.
increaseViewCount() 호출 후 postRepository.save(post)를 명시적으로 부르고 계신데요, @Transactional 어노테이션이 있으면 트랜잭션 안에서 엔티티 상태가 변경될 때 Hibernate의 dirty checking이 자동으로 감지해서 커밋 시 UPDATE 쿼리를 날려줍니다. save를 명시적으로 부를 필요가 없어요!
현재 PostService에 @Transactional이 없는 상태라 increaseViewCount의 변경이 DB에 반영되지 않을 수도 있어요. @Transactional을 추가해주시면 save 호출도 함께 제거할 수 있습니다.
| spring.jpa.hibernate.ddl-auto=update | ||
| spring.jpa.hibernate.ddl-auto=create-drop | ||
| spring.jpa.show-sql=true | ||
| spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect No newline at end of file |
There was a problem hiding this comment.
ddl-auto=create-drop은 애플리케이션이 시작될 때마다 테이블을 새로 만들고 종료 시 삭제해서, 재시작하면 데이터가 모두 사라집니다. 개발 초기에 스키마 확인용으로 쓰셨을 것 같은데, update나 validate로 되돌려두시는 게 안전할 것 같아요.
| return PostResponse.from(post); | ||
| } | ||
|
|
||
| public PostResponse createPost(PostCreateRequest request) { |
There was a problem hiding this comment.
title과 content의 null/blank 체크를 서비스에서 직접 하고 계신데, PostCreateRequest에 이미 @NotBlank가 달려있으니 컨트롤러에 @Valid를 추가하면 이 검증 로직은 서비스에서 제거해도 됩니다. 검증은 진입점(컨트롤러)에서 한 번만 하는 게 역할 분리에 더 맞아요!
|
CRUD 기능을 정말 꼼꼼하게 다 구현하셨네요! 특히 별도의 .http 파일로 테스트 환경까지 구성하신 점이 인상 깊어요 더 좋은 코드를 위해 몇 가지 의견 드려요! |
1. 과제 요구사항 중 구현한 내용
2. 핵심 변경 사항
3. 실행 및 검증 결과
구현 내용:
4. 완료 사항
5. 추가 사항
closed #이슈번호제출 체크리스트
{이름}/main브랜치다{이름}/{숫자}주차브랜치다Reviewer 참고