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

[BE] 유저 생성 및 조회 기능 구현 #8

Merged
merged 9 commits into from
Aug 11, 2024
Merged

[BE] 유저 생성 및 조회 기능 구현 #8

merged 9 commits into from
Aug 11, 2024

Conversation

KoKimSS
Copy link
Member

@KoKimSS KoKimSS commented Aug 9, 2024


🚀 어떤 기능을 구현했나요 ?

  • 유저 생성 및 조회 기능 개발
  • 유저 생성시 루트 폴더 생성

🔥 어떻게 해결했나요 ?

📝 어떤 부분에 집중해서 리뷰해야 할까요?

📚 참고 자료, 할 말

- 폴더 메타데이터 스키마 수정
- 유저 스키마 수정
- 유저 생성시 루트 폴더 생성
@KoKimSS KoKimSS added the ✅기능 개발 Further information is requested label Aug 9, 2024
@KoKimSS KoKimSS added this to the 파일 조회 및 다운로드 milestone Aug 9, 2024
@KoKimSS KoKimSS linked an issue Aug 9, 2024 that may be closed by this pull request
2 tasks
Copy link
Collaborator

@kariskan kariskan left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!

private final UserService userService;

@GetMapping
@RequestMapping("/{userId}")
Copy link
Collaborator

Choose a reason for hiding this comment

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

GetMapping에 uri 명시하면 RequestMapping은 필요 없지 않나요?

Copy link
Member Author

@KoKimSS KoKimSS Aug 10, 2024

Choose a reason for hiding this comment

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

이 부분은 수정하겠습니다.

@GetMapping
@RequestMapping("/{userId}")
public ResponseEntity<UserDto> getUser(@PathVariable Long userId) {
return ResponseEntity.ok(userService.findById(userId));
Copy link
Collaborator

Choose a reason for hiding this comment

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

ResponseEntity로 래핑해서 보내는 이유가 있을까요? RestController 붙이면 UserDto나 ResponseEntity나 같은 형태로 응답된다고 알고 있어서요

Copy link
Member Author

Choose a reason for hiding this comment

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

평소에 이유를 크게 생각하지 않고 ResponseEntity로 반환을 해주었는데요.
찾아보니 저희 프로젝트에는 Dto 자체를 반환해주는 것이 맞는 것 같다는 생각이 드네요.

-> 저희는 GlobalExceptionHandler 가 예외 발생 상황을 책임지기 때문에 controller는 dto를 반환하는 로직만 책임지면 될 것 같습니다. ResponseEntity를 사용하여 Header나 HttpStatusCode 등을 동적으로 변경할 일이 없습니다.

-> Response dto 가 정해져있기 때문에 굳이 ResponseEntity<? extends T>를 사용하여 dto를 상속받는 모든 객체를 반환할 수 있게 허용할 가능성을 열어 둘 필요가 없을 것 같습니다.

참조


@PostMapping
@RequestMapping
public ResponseEntity<UserDto> createUser(@RequestBody CreateUserReqDto req) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

@ResponseStatus(value = HttpStatus.CREATED)
이거 붙이면 좋을 것 같습니다.

Copy link
Member Author

Choose a reason for hiding this comment

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

변경하겠습니다.


@Getter
@NoArgsConstructor
public class UserDto {
Copy link
Collaborator

Choose a reason for hiding this comment

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

dto는 필드 별로 없어서 record로 만들어도 좋을 것 같은데 어떻게 생각하시나요?

Copy link
Member Author

Choose a reason for hiding this comment

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

좋은 것 같습니다 ! record 로 바꾸겠습니다


@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
Copy link
Collaborator

Choose a reason for hiding this comment

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

@transactional 어노테이션은 메서드마다 작성하는게 어떤가요? 가독성도 떨어지고, 밑에처럼 어노테이션 중복으로 재사용하면 혼동될 거 같아요.

Copy link
Member Author

Choose a reason for hiding this comment

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

공통적으로 @transactional(readOnly = true) 를 사용하여 불필요한 더티 체킹이 일어나지 않게 막고(실수 방지) 필요한 메소드에는 따로 @transactional(readOnly = false) 를 사용해주는 방식으로 사용했었습니다.

가독성 vs 실수방지 의 문제인 것 같네요 ! 댓글 다시 주시면 감사하겠습니다.

Copy link
Collaborator

@kariskan kariskan Aug 10, 2024

Choose a reason for hiding this comment

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

지금은 readonly 밖에 없지만 나중에 rollback, propagation 이런 것도 사용하게 되면 오히려 더 헷갈리지 않을까요? + 이렇게 사용할 때마다 클래스 맨 위에 보면서 확인해야 하는것도 불편할 것 같아요

Copy link
Collaborator

Choose a reason for hiding this comment

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

저도 중진님과 같은 이유로 Transactional 어노테이션은 메소드마다 작성하는 것이 좋다고 생각합니다. 트랜잭션이라는 의미로만 봤을 때도 메소드마다 작성하는 것이 더 좋은 것 같아요.


public UserDto findById(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new CustomException(HttpStatus.BAD_REQUEST, "잘못된 id 입니다"));
Copy link
Collaborator

Choose a reason for hiding this comment

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

404 아닌가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

맞네요 수정하겠습니다 !

public UserDto save(CreateUserReqDto req) {
LocalDateTime now = LocalDateTime.now();

FolderMetadata rootFolder = folderMetadataRepository.save(FolderMetadata.builder()
Copy link
Collaborator

Choose a reason for hiding this comment

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

builder가 서비스 코드에 있어서 별 역할 하지 않는데도 길어보이는데 FolderMetadataFactory 같은 클래스를 만들고 static 메서드로 빼는게 어떨까요

Copy link
Member Author

Choose a reason for hiding this comment

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

추가적인 변경사항이 없다고 생각하는 경우 factoryMethod를 만드는 것이 좋다고 생각합니다 ! 아직 개발 초기이기 때문에 builder()로 변경 가능성을 열어 두는 것은 어떨까요 ? -> 나중에 리팩토링을 하는 형식으로

Copy link
Collaborator

Choose a reason for hiding this comment

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

아 빌더를 안쓰는게 아니라 엔티티 생성하는 부분을 따로 빼는게 어떤지 말씀드리는 거였습니다

- User, FolderMetadataFactory 정적 팩토리 메소드 추가
- User, FolderMetadataFactory 생성 팩토리 메소드로 변경
- ResponseEntity -> dto 로 변경
@KoKimSS KoKimSS requested review from kariskan and seungh1024 August 10, 2024 12:28
@KoKimSS
Copy link
Member Author

KoKimSS commented Aug 10, 2024

리뷰해 주신 부분 수정했습니다

Copy link
Collaborator

@kariskan kariskan left a comment

Choose a reason for hiding this comment

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

요 두개만 봐주시면 될 듯 합니다!


@NoArgsConstructor
@Getter
public class CreateUserReqDto {
Copy link
Collaborator

Choose a reason for hiding this comment

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

이것도 record로 만들면 되겠네요.

@@ -0,0 +1,4 @@
package com.woowacamp.storage.domain.user.dto;

public record UserDto(Long id, Long rootFolderId, String userName) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

request든지 response든지 dto에서는 not null인게 보장되면 래퍼타입 쓰지않고 원시 타입 써도 될 듯 합니다.

@KoKimSS
Copy link
Member Author

KoKimSS commented Aug 11, 2024

요 두개만 봐주시면 될 듯 합니다!

두개 고쳤습니다 !

@KoKimSS KoKimSS requested a review from kariskan August 11, 2024 11:37
@kariskan kariskan merged commit d704793 into main Aug 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✅기능 개발 Further information is requested
Projects
None yet
Development

Successfully merging this pull request may close these issues.

유저를 생성한다.
4 participants