Today I Learned

2024 스파르타 내일배움캠프 Sping 트랙 참여 // day36

shinelee26 2024. 11. 20. 22:11

오늘 진행한 학습 요약

1. CH 4 뉴스피드 프로젝트

  • 개발 프로세스 가이드
    • 0단계 : 목표 정하기! (Growth Mindset)
    • 1단계 : 팀 노션 작성하기!
    • 2단계 : 프로젝트 아이디어 구상하기!
    • 3단계 : 와이어프레임 작성하기!
    • 4단계 : ERD 작성하기!
    • 5단계 : API 명세 작성하기!
    • 6단계 : S.A 작성 및 피드백 받기!
    • 7단계 : 본격적인 백엔드 개발하기!
    • 8단계 : 테스트 및 버그 수정하기!
뉴스피드 프로젝트 (gameTalk) Git-hub 링크 : https://github.com/Newbiekk-kkh/GameTalk

 

2. 알고리즘 코드카다  Day36(작성 생략)

CodingTest Git-hub 링크 : https://github.com/chews26/CodingTest

 


학습 정리

1. CH 4 뉴스피드 프로젝트

 

개발 프로세스 가이드

  • 7단계 : 본격적인 백엔드 개발하기!
    •  
    • 프로필관리 기능을 맡아 기능을 개발하였다.
    • Controller
      •     // 프로필 조회 기능
            @GetMapping("/users/{id}")
            public ResponseEntity<UserResponseDto > findUserById(@PathVariable Long id, HttpServletRequest request) {
                UserResponseDto userResponseDto = userService.findUserById(id);
                return new ResponseEntity<>(userResponseDto, HttpStatus.OK);
            }
        
            // 프로필 수정 기능
            @PatchMapping("/users/{id}")
            public ResponseEntity<UserResponseDto> updateUser(
                    @PathVariable Long id,
                    @Valid
                    @RequestBody Map<String, Object> updates,
                    HttpServletRequest request) {
                UserResponseDto userResponseDto = userService.updateUser(id, updates);
                return new ResponseEntity<>(userService.updateUser(id, updates), HttpStatus.OK);
            }
    • Dto
      • @Getter
        public class UserUpdateResponseDto {
        
            @NotBlank
            private final String username;
        
            @NotBlank
            private final String email;
        
            public UserUpdateResponseDto(String username, String email) {
                this.username = username;
                this.email = email;
            }
        }
    • Entity
      • @Getter
        @Setter
        @Entity
        @Table(name = "user")
        public class User extends BaseEntity {
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            private Long id;
        
            @Column(nullable = false, unique = true)
            private String email;
        
            @Column(nullable = false)
            private String password;
        
            @Column(nullable = false)
            private String username;
        
        
            public User(String email, String password, String username, boolean isActivated) {
                this.email = email;
                this.password = password;
                this.username = username;
            }
              
            public static UserResponseDto toDto(User user) {
                return new UserResponseDto(
                        user.getUsername(),
                        user.getEmail()
                );
            }
        }
    • Repository
      • @Repository
        public interface UserRepository extends JpaRepository<User, Long> {
          
           Optional<User> findUserByUsername(String username);
        
            default User findUserByUsernameOrElseThrow(String username) {
                return findUserByUsername(username).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
        
            }
        
            // UserId 존재 유무 확인
            default User findByIdOrElseThrow(long id) {
                return findById(id).orElseThrow(()-> new ResponseStatusException(HttpStatus.NOT_FOUND, "존재하지 않는 회원입니다"));
            }
        
            // Email 존재 유무 확인
            Optional<User> findByEmail(String email);
        
            default User findByEmailOrElseThrow(String email) {
                return findByEmail(email).orElseThrow(()-> new ResponseStatusException(HttpStatus.NOT_FOUND, "존재하지 않는 이메일입니다."));
            }
        }
    • Service
      • @Service
        @RequiredArgsConstructor
        public class UserService {
        
            private final UserRepository userRepository;
        
            // 프로필 조회 기능
            public UserProfileResponseDto findUserById(Long userId) {
                User user = userRepository.findByIdOrElseThrow(userId);
                return User.toDto(user);
            }
        
            // 프로필 수정 기능
            public UserUpdateResponseDto updateUser(Long userId, Map<String, Object> updates) {
                User findUser = userRepository.findByIdOrElseThrow(userId);
        
                updates.forEach((key, value) -> {
                    switch (key) {
                        case "username":
                            findUser.setUsername((String) value);
                            break;
                        case "email":
                            findUser.setEmail((String) value);
                            break;
                        case "password":
                            // todo 패스워드 암호화 기능 연동 필요
                            String encodedPassword = passwordEncoder.encode((String) value);
                            findUser.setPassword((String) value);
                            break;
                        default:
                            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "잘못된 입력값입니다 " + key);
                    }
                });
                userRepository.save(findUser);
                return new UserUpdateResponseDto(findUser.getUsername(), findUser.getEmail());
            }
        }

  • 8단계 : 테스트 및 버그 수정하기!
    • 😎 API 테스트 
      • 테스트를 위해 회원가입, 로그인 기능을 모두 구현하고 프로필 관리 기능을 구현하여 API테스트를 진행했다.
      • API가 정상적으로 동작함을 확인 한 후 회원가입, 로그인기능을 지우고 커밋했다.
    • 🤔 Git-Hub Pull request
      • 각자의 기능을 완료한 후 각자의 기능을 개발한 feature 브랜치에서 develop 브랜치로 pull request를 진행했다.
      • 충돌이 나서 Resolve conflict를 하려는데 버튼이 비활성화되어있었다.
      • 이유를 찾아보니 gitignore에  application.properties를 추가한것이 문제였다.
      • application.properties을 gitignore에서 제외 후 커밋한 뒤 다시 pull request를 진행하니 Resolve conflict버튼이 활성화되었다.
      • 충돌된 코드를 수정 후 develop 브랜치로 pull request가 완료되었다.
    • 😎 팀과 코드 리뷰
      • 팀과 코드 리뷰를 하며 몇가지 수정사항이 발생하였다.
      • 프로필 수정(이름, 이메일, 비밀번호 수정) 기능을 이용할때는 로그인로직시 수행하던 패턴(이메일 형식, 비밀번호 규칙)등이 적용이 되어있지 않았다. 따라서 이 기능을 추가하였다.
      • UserDeleteResponseDto, UserUpdateResponseDto는 다른 팀원이 작성한 UserResponseDto와 내용이 중복되어 UserResponseDto로 사용하도록 수정 및 파일 삭제를 진행하였다.
      • 내일 점심에 수정한 코드를 다시 검토하고 필수구현이 완료되었다고 판단되면 추가구현을 할 예정이다!