728x90
320x100
🎯 오늘의 목표
- 회원(User) 도메인 회원가입 API 구현
⚙️ 진행한 작업
- 회원(User) 도메인 회원가입 API 구현
- repository, service, controller 수정 및 구현
- 기타 등등 수정
🛠️ 개발내용
📌 회원 레파지토리 추가 (UserRepository.java)
package ddururi.bookbookclub.domain.user.repository;
import ddururi.bookbookclub.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
//생략//
//닉네임 중복 확인 (API 용도)
boolean existsByNickname(String nickname);
}
- API 용도로 사용할 닉네임 중복확인 메서드를 추가하였음.
📌 회원 서비스 수정 및 추가 (UserService.java)
package ddururi.bookbookclub.domain.user.service;
import ddururi.bookbookclub.global.exception.DuplicateNicknameException;
import ddururi.bookbookclub.domain.user.dto.UserLoginRequest;
import ddururi.bookbookclub.domain.user.dto.UserResponse;
import ddururi.bookbookclub.domain.user.dto.UserSignupRequest;
import ddururi.bookbookclub.domain.user.dto.UserUpdateRequest;
import ddururi.bookbookclub.domain.user.entity.User;
import ddururi.bookbookclub.domain.user.repository.UserRepository;
import ddururi.bookbookclub.global.exception.DuplicateEmailException;
import ddururi.bookbookclub.global.exception.UserNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder passwordEncoder;
//회원가입
public UserResponse signup(UserSignupRequest request){
validateDuplicateEmail(request.getEmail());
validateDuplicateNickname(request.getNickname());
User user = User.create(
request.getEmail(),
passwordEncoder.encode(request.getPassword()),
request.getNickname()
);
userRepository.save(user);
return UserResponse.from(user);
}
//이메일 중복 확인
private void validateDuplicateEmail(String email) {
if (userRepository.existsByEmail(email)) {
throw new DuplicateEmailException();
}
}
//닉네임 중복 확인
private void validateDuplicateNickname(String nickname) {
if (userRepository.existsByNickname(nickname)) {
throw new DuplicateNicknameException();
}
}
// 이메일 중복 확인 (API 용도)
public boolean isEmailDuplicate(String email) {
return userRepository.existsByEmail(email);
}
//닉네임 중복 확인 (API 용도)
public boolean isNicknameDuplicate(String nickname) {
return userRepository.existsByNickname(nickname);
}
//생략//
- 이메일과 닉네임 중복하는 메소드를 따로 빼고, API용도로 사용할 이메일/닉네임 중복 메서드로 생성하였음.
📌 회원 컨트롤러 구현 (UserController.java)
package ddururi.bookbookclub.domain.user.controller;
import ddururi.bookbookclub.domain.user.dto.LoginResponse;
import ddururi.bookbookclub.domain.user.dto.UserLoginRequest;
import ddururi.bookbookclub.domain.user.dto.UserResponse;
import ddururi.bookbookclub.domain.user.dto.UserSignupRequest;
import ddururi.bookbookclub.domain.user.service.UserService;
import ddururi.bookbookclub.global.common.ApiResponse;
import ddururi.bookbookclub.global.jwt.JwtUtil;
import ddururi.bookbookclub.global.security.CustomUserDetails;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
private final JwtUtil jwtUtil;
//회원가입
@PostMapping
public ResponseEntity<ApiResponse<UserResponse>> signup(@Valid @RequestBody UserSignupRequest request) {
UserResponse response = userService.signup(request);
return ResponseEntity.ok(ApiResponse.success(response));
}
//이메일 중복 확인
@GetMapping("/check-email")
public ResponseEntity<ApiResponse<Boolean>> checkEmailDuplicate(@RequestParam String email) {
boolean isDuplicate = userService.isEmailDuplicate(email);
return ResponseEntity.ok(ApiResponse.success(isDuplicate));
}
//닉네임 중복 확인
@GetMapping("/check-nickname")
public ResponseEntity<ApiResponse<Boolean>> checkNicknameDuplicate(@RequestParam String nickname) {
boolean isDuplicate = userService.isNicknameDuplicate(nickname);
return ResponseEntity.ok(ApiResponse.success(isDuplicate));
}
}
[Postman을 통한 테스트]
POST http://localhost:8080/api/users
Content-Type: application/json
{
"email": "test@example.com",
"password": "12345678",
"nickname": "북덕이"
}
📌 UserSignupRequest 수정
package ddururi.bookbookclub.domain.user.dto;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class UserSignupRequest {
@Email(message = "이메일 형식이 올바르지 않습니다.")
@NotBlank(message = "이메일은 필수입니다.")
private String email;
@NotBlank(message = "비밀번호는 필수입니다.")
@Size(min = 6, max = 20, message = "비밀번호는 6자 이상 20자 이하로 입력해주세요.")
private String password;
@NotBlank(message = "닉네임은 필수입니다.")
@Size(max = 30, message = "닉네임은 최대 30자까지 입력할 수 있습니다.")
private String nickname;
}
- @vaild 어노테이션 활용을 위해 dto에 어노테이션 추가
[기타 추가 수정]
📌 회원(User) 엔티티 수정
package ddururi.bookbookclub.domain.user.entity;
import ddururi.bookbookclub.domain.user.enums.Role;
import ddururi.bookbookclub.domain.user.enums.UserStatus;
import jakarta.persistence.*;
import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class User {
//생략//
@Column(unique = true, nullable = false)
private String email;
//생략//
}
- 이메일 필드에 unique 조건을 추가하였음.
728x90
320x100
'💻 뚝딱뚝딱 > 북북클럽' 카테고리의 다른 글
[개발일지 #005] 로그인 구현 (Feat.JWT 기반 인증) (0) | 2025.04.22 |
---|---|
[개발일지 #004] 회원 정보 수정 API 구현 (0) | 2025.04.22 |
[개발일지#002] 회원(User) 도메인 단위 테스트 (0) | 2025.04.18 |
[개발일지#001] 회원 도메인(User) 개발 (0) | 2025.04.18 |
[개발일지#000] 프로젝트 생성 (프로젝트 생성, MySQL 연결, 개발 편의 설정, 패키지 설정 등) (0) | 2025.04.16 |