-
Notifications
You must be signed in to change notification settings - Fork 203
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
[5기 남은찬, 박주한] Spring Boot JPA 게시판 구현 미션 제출합니다. #267
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: name [email protected]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
과제 고생하셨습니다~!!
전반적으로 깔끔하게 작성해주신 점이 좋았습니다.
아쉬웠던 부분은 유효성 검사가 다 빠져있는데 이 부분은 조금 고민해보시면 좋을 것 같습니다!
|
||
@LastModifiedDate | ||
@Column(columnDefinition = "TIMESTAMP") | ||
private LocalDateTime updatedDate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
질문) createdDate
는 protected
로 updatedDate
는 private
으로 선언하신 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
왜 이렇게 선언돼있는지 모르겠네요 .. 실수한 것 같아요 수정하겠습니다!
|
||
@LastModifiedDate | ||
@Column(columnDefinition = "TIMESTAMP") | ||
private LocalDateTime updatedDate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
질문) ZonedDateTime
,Instant
대신 LocalDateTime
을 사용하신 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
솔직히 특별한 이유 없고, 자바에선 항상 LocalDateTime 만 사용해와서 사용했습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지나가다가 발견해서 코멘트 남깁니다.
면접에서 자바8 기능에 대하여 종종 물어볼 수도 있어서 참고해보시면 좋을 것 같아요
https://min103ju.github.io/java/localdatetime/
|
||
@LastModifiedDate | ||
@Column(columnDefinition = "TIMESTAMP") | ||
private LocalDateTime updatedDate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LocalDateTime
필드의 네이밍을 ~Date
로 선언하신 이유가 있을까요?
LocalDate
필드를 사용할 일이 있을 때 변수명을 보고 datetime
값을 가지고 있는지 date
값을 가지고 있는지 확인하기 어려울 것 같습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 정확한 네이밍 으로 수정하겠습니다!
|
||
@LastModifiedDate | ||
@Column(columnDefinition = "TIMESTAMP") | ||
private LocalDateTime updatedDate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요구사항은 created_at
과 created_by
를 만드는 걸로 기억하고 있는데 created_by
는 빠진 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 빠트린 created_by 필드도 추가해야겠습니다
@RequiredArgsConstructor | ||
public class BoardException extends RuntimeException { | ||
|
||
private final String message; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
질문) RuntimeException
을 상속받았으면 message
를 인자로 전달해줄 수 있는데 다시 정의하신 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
생각해보니 없어도 되는 필드같네요! 수정하겠습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
테스트는 잘 작성해주셨는데 AsciiDoc 다른 파일들 (index.adoc 등?)은 구현 안하셨을까요?
|
||
public static Post getPost(Long id) { | ||
Post post = getPost(); | ||
ReflectionTestUtils.setField(post, "id", id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get을 하는데 안에서 그 값을 설정하는게 어색한 거 같은데 어떻게 생각하시나요?
setField
를 사용할 땐 사용하는게 맞나 구조적으로 한 번 더 고민해보시면 좋습니다.
Post post = PostFixture.getPost(1L); | ||
User user = UserFixture.getUser(); | ||
CreatePostRequest request = new CreatePostRequest(post.getTitle(), post.getContent(), 1L); | ||
|
||
given(postRepository.save(any(Post.class))) | ||
.willReturn(post); | ||
given(userRepository.findById(1L)) | ||
.willReturn(Optional.of(user)); | ||
|
||
//when | ||
Long result = postService.createPost(request); | ||
|
||
//then | ||
assertThat(result).isEqualTo(1L); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
테스트 픽스처 생성 부분에서 어색한 부분이 있습니다!
Post
를 생성하는 테스트인데 픽스처에서 Post
를 미리 만들어야할까요?
테스트하려는 부분도 어색한 부분이 있습니다.
ID는 유일성을 보장하는 값으로, 기존에 없는 값으로 어떤 값이 나오게 될지 모를텐데 ID가 일치하는지 확인해도 될까요?
실제로 유저가 게시글을 만들 때 잘 생성되었는지 확인하고 싶을 때, ID가 예상한대로 나왔구나 생각할지 고민해보시면 좋습니다.
@Transactional | ||
@AutoConfigureMockMvc | ||
@ExtendWith(RestDocumentationExtension.class) | ||
public abstract class ApiTestSupport extends TestContainerSupport { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
질문) ApiTest
를 하는데 TestContainer
설정을 넣으신 이유가 궁금합니다.
ApiTest
를 할때마다 데이터베이스가 꼭 필요할까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
local은 datasource
를 mysql
을 쓰고, 기본은 testcontainers
를 쓰는게 살짝 profile 분리가 어색해 보입니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
과제 고생하셨습니다.
리뷰 확인부탁드힙니다. ~~
public class BaseEntity { | ||
|
||
@CreatedDate | ||
@Column(columnDefinition = "TIMESTAMP") | ||
protected LocalDateTime createdDate; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
인스턴스화하지 않을 객체이니 추상클래스로 변경해보는 것은 어때요 ??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앗 맞는말인거같아요! 수정하겠습니다
@Column(columnDefinition = "TIMESTAMP") | ||
private LocalDateTime updatedDate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개인적으로 모든 엔티티 필드에 컬럼 애너테이션을 달고 컬럼 이름을 명시하는 것을 선호해요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 한번 적용해보겠습니다
public ResponseEntity<Long> savePost(@RequestBody CreatePostRequest request) { | ||
Long postId = postService.createPost(request); | ||
|
||
return ResponseEntity.ok(postId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
응답 값만 보아서는 어떤 값이 리턴이 되는 지 알기 어렵습니다.
객체화해서 그 객체 필드에 postId 를 전달하는 것이 명확할 것 같아여
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분에 대해서 솔직히 id 를 응답할 필요가 없을거같아서 리턴 타입 자체를 불린으로 바꾸려 하는데, 불린에 대한 응답도 한번 객체화하는게 좋을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
불린은 괜찬을듯
} | ||
|
||
@GetMapping | ||
public ResponseEntity<PostListResponse> getPosts(@PageableDefault Pageable pageable) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PageableDefault
를 사용하면 어떤 효과가 있나여 ??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
상세한 size
나 page
에 대해서 특별한 요구사항을 정하지 않아서 페이징 정보를 받지 않았을 때, 기본으로 @PageableDefault
에서 지정되는 디폴트 값으로 설정하려고 사용했습니다!
public Post(String title, String content, User user) { | ||
this.title = title; | ||
this.content = content; | ||
this.user = user; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
정적팩토리메서드 패턴을 바꿔도 좋을 것 같아요
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) | ||
public record CreatePostRequest( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fieldVisibility = JsonAutoDetect.Visibility.ANY 는 어떤 역할을 하나요 ????
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
정말 이유를 모르겠지만 @RequestBody
에서 레코드를 역직렬화를 못해서 지정했습니다
항상 이상없이 잘 돼왔었는데... 일단 급한대로 해당 어노테이션으로 해결했습니다
public record PostListResponse( | ||
Page<PostResponse> responses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reponses 보다는 postInfos 혹은 posts 정도가 나은 것 같아아요
@Table(name = "users") | ||
public class User extends BaseEntity { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
테이블 이름을 복수형으로 선언하신 이유가 있을까요???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
user 가 mysql 에서 이미 사용중인 네이밍이라 테이블 이름으로 사용이 안되는거로 알고있어서 복수형으로 선언했습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아하 이미 사용중인 네임이였군여, 어쩐지 대부분 MEMBER, ACCOUNT 이런식으로 테이블 이름을 사용하더라고요 ㅎㅎㅎ
</encoder> | ||
</appender> | ||
|
||
<logger name="io.undertow" level="OFF"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
언더토우 사용하셨나요 ??? ㅎㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 로거를 잘 보고싶어서 로그백을 가져오다가 필요 없는 부분이 포함되었습니다 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아하 다른거 써보시길 기대했는데 아니였구만요 ㅋㅋㅋ
|
||
import java.nio.charset.StandardCharsets; | ||
|
||
@SpringBootTest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요거 없이 테스트할 수 없을까요 ???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
controller 로 단위테스트로 할 수 있었는데, 컨트롤러 테스트 하는 겸 통합테스트를 한번 수행하려고 @SpringBootTest
를 사용했습니다
현재 성공 케이스에 대해서만 통합테스트로 진행하는데 이런식으로 간단한 통합테스트만 진행할바에 단위테스트로 진행하는게 좋을까요?
요구 사항
SpringDataJPA 를 설정한다.
엔티티를 구성한다
API를 구현한다.
REST-DOCS를 이용해서 문서화한다.
✅ PR 포인트 & 궁금한 점