Skip to content
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

[4기 원건희 & 박상민] Springboot-board 1차 PR 입니다. #225

Open
wants to merge 60 commits into
base: weonest-&-sangmin
Choose a base branch
from

Conversation

weonest
Copy link

@weonest weonest commented Aug 1, 2023

📌 과제 설명

  • 페어 프로그래밍의 장점을 살리기 위해 인텔리제이의 Code with me를 사용하여 게시판 (원건희), 유저 (박상민) 를 구현하였습니다.
  • API 명세를 위한 restdocs를 적용하였습니다.

✅ PR 포인트 & 궁금한 점

  • PostControllerfindByCondition 부분에서 파라미터들을 @RequestParam으로 받는 방법과 PostFindRequest라는 요청 객체를 만들어 받는 방법을 고민 했는데 어떤 부분이 더 좋을지 궁금합니다. 또한 해당 부분에서 분기가 4가지로 나뉘고 있는데 이러한 분기를 효율적으로 줄이는 방법도 궁금합니다!

weonest and others added 30 commits July 28, 2023 16:57
src/main/java/com/jpaboard/domain/post/PostConverter.java Outdated Show resolved Hide resolved
Comment on lines +11 to +12
@Query("select p from Post p where p.title like %:title% or p.content like %:content% or p.title like %:keyword% or p.content like %:keyword%")
Page<Post> findAllByCondition(String title, String content, String keyword, Pageable pageable);
Copy link
Member

Choose a reason for hiding this comment

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

음,,, 지금은 어쩔 수 없지만 이런 쿼리는 굉장히 위험할 수 있습니다! 왜 일까요?

Copy link
Author

@weonest weonest Aug 3, 2023

Choose a reason for hiding this comment

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

쿼리에 의존적인 코드이기 때문인 것 같습니다! 요구사항이 변경된다면 쿼리도 수정해줘야 하고 로직도 변경해줘야 하며, 입력하다가 실수하기도 좋은 코드이기 때문이기도 한 것 같습니다.
추가로 굉장히 위험하다고 하시니 뭔가 보안적인 이유가 있을 것 같은데 혹시 Sql Injection 문제일까요?
만약 이러한 문제가 맞다면 멘토님의 설명을 들어보고 싶습니다!

Copy link
Member

Choose a reason for hiding this comment

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

아뇨 성능이 너무 안 나와서..ㅎ

src/main/java/com/jpaboard/domain/user/User.java Outdated Show resolved Hide resolved
return ResponseEntity.ok(userService.findUserById(id));
}

@PutMapping("/{id}")
Copy link
Member

Choose a reason for hiding this comment

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

PUT Method은 해당 리소스가 없을 경우 어떻게 동작하나요?

src/main/resources/application.yml Outdated Show resolved Hide resolved
Comment on lines +16 to +18
PostPageResponse findPosts(Pageable pageable);

PostPageResponse findPostsByCondition(PostSearchRequest request, Pageable pageable);

Choose a reason for hiding this comment

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

PostSearchRequest의 전체 속성이 비어있다면 두 메서드는 같은게 아닌가요?

Copy link
Author

Choose a reason for hiding this comment

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

전체 속성이 비어있으면 아무런 결과를 반환하지 않기에 분리를 하게 되었습니다.. 좀 더 나은 JPQL 쿼리문을 작성해야 하는데 방법을 잘 모르겠습니다

Choose a reason for hiding this comment

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

전체 속성이 null인 경우에 where 구문을 spring data jpa에서 어떻게 생성하는지 확인해볼 필요가 있겠네요.
다이나믹 쿼리를 작성하는 예시가 나와 있어서 적용해봐도 좋을 것 같네요.

https://tecoble.techcourse.co.kr/post/2022-10-11-jpa-dynamic-query/

Comment on lines +11 to +12
@Query("select p from Post p where p.title like %:title% or p.content like %:content% or p.title like %:keyword% or p.content like %:keyword%")
Page<Post> findAllByCondition(String title, String content, String keyword, Pageable pageable);
Copy link
Member

Choose a reason for hiding this comment

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

아뇨 성능이 너무 안 나와서..ㅎ

return ResponseEntity.ok(userService.findUserById(id));
}

@PutMapping("/{id}")
Copy link
Member

Choose a reason for hiding this comment

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

저는 1,2를 쓰는 것 같습니다!

userServiceImpl.updateUser(user.getId(), request);

// then
verify(userRepository, atMostOnce()).findById(user.getId());
Copy link
Member

Choose a reason for hiding this comment

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

유저 조회 여부를 검증하는 이유가 있나요?

Copy link

@seung-hun-h seung-hun-h left a comment

Choose a reason for hiding this comment

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

리뷰 남겼습니다~

Comment on lines +37 to +50
@GetMapping
public ResponseEntity<PostPageResponse> postFindAll(@PageableDefault Pageable pageable) {
PostPageResponse response = postService.findPosts(pageable);
return ResponseEntity.ok(response);
}

@GetMapping("/search")
public ResponseEntity<PostPageResponse> findByCondition(
@ModelAttribute PostSearchRequest request,
@PageableDefault Pageable pageable
){
PostPageResponse response = postService.findPostsByCondition(request, pageable);
return ResponseEntity.ok(response);
}

Choose a reason for hiding this comment

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

두 api를 합칠 수 있을 것 같네요

import lombok.Getter;

@Getter
public enum ErrorCodeWithDetail {

Choose a reason for hiding this comment

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

WithDetail은 빼도 되지 않을까요??

Comment on lines +8 to +10
BAD_REQUEST(400, "C000", "잘못된 요청입니다."),
ENTITY_NOT_FOUND(404, "C001", "해당 엔티티를 찾을 수 없습니다."),
INTERNAL_SERVER_ERROR(500, "C999", "서버 내부 에러입니다.");

Choose a reason for hiding this comment

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

C000같은 code를 따로 만드신 이유가 있을까요?
어떤 유형의 에러인지 구분하기 위해서라면 조금더 가독성있게 만들어주는 편이 좋을 것 같아요.
아니면 어떤 에러인지 문서화를 해주는 것이 좋겠네요.

@Mock
private UserRepository userRepository;

Random random = new Random();

Choose a reason for hiding this comment

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

난수를 생성할 때 Random은 잘 사용하지 않는 것 같아요. 여러가지 방법이 있긴한데 java17에 RandomGenerator라는 것이 있더라구요.

https://recordsoflife.tistory.com/1055

Comment on lines +156 to +162
given(postRepository.findById(postId)).willReturn(Optional.of(post));

//when
postService.updatePost(postId, request);

//then
verify(post, atMostOnce()).update(request.title(), request.content());

Choose a reason for hiding this comment

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

별건 아니지만 BDDMockito.givenMockito.verity를 혼용해서 사용하고 계셔서 차이를 알고 계시면 좋겠네요.
개인적으론 둘 중 하나를 선택해서 사용합니다

https://tecoble.techcourse.co.kr/post/2020-09-29-compare-mockito-bddmockito/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants