이번엔 도메인 설정 이후 컨트롤러와 서비스를 만들어 보도록 하겠습니다.
먼저 반환 형식을 맞추려고 합니다.
Response
{
"status" : "success",
"message" : "회원 가입 성공",
"data" : {
"userId" : 1
}
}
위와 같은 형태로 반환을 하기 위해 CommonResponse와 ResultDto를 작성하도록 하겠습니다.
CommonResponse
@Getter
@Builder
public class CommonResponse<Data> {
private String status;
private String message;
private HttpStatus httpStatus;
private Data data;
}
ResultDto
@Getter
@Setter
@AllArgsConstructor
@RequiredArgsConstructor(staticName = "in")
public class ResultDto<Data> {
private final String status;
private final String message;
private Data data;
}
CommonResponse로 HttpStatus와 status, message, data를 넘겨주고 ResultDto에서 설정을 해서 ResponseEntity로 반환해주려고 합니다. ResultDto에 Data 부분에 final이 붙지 않은 이유는 RequiredArgsConstructor의 staticName을 사용하고 있는데 Data가 없는 반환이 있을 수도 있어 Data가 있다면 Setter로 따로 삽입했습니다. 사용은 컨트롤러에서 보여드리도록 하겠습니다.
SignupController
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1")
public class SignupController {
private final BasicSignupService basicSignupService;
@PostMapping("/signup/basic")
public ResponseEntity<ResultDto<SignupResponseDto>> signup(@RequestBody BasicSignupRequestDto basicSignupRequestDto) {
CommonResponse<Object> commonResponse = basicSignupService.signupResponse(basicSignupRequestDto);
ResultDto<SignupResponseDto> result = ResultDto.in(commonResponse.getStatus(), commonResponse.getMessage());
result.setData((SignupResponseDto) commonResponse.getData());
return ResponseEntity.status(commonResponse.getHttpStatus()).body(result);
}
컨트롤러에서 @RequestBody로 넘어온 데이터를 BasicSignupRequestDto로 받아주고 서비스로 넘겨주고 반환 값을 가져오는 코드 입니다.
CommonResponse<Object> 형태로 값을 받아오고 ResultDto.in으로 status와 message를 가져옵니다.
여기서 저는 Data에 userId를 반환해주기 위해 SignupResponseDto를 만들어 userId를 반환해주었습니다.
위에 설명한 것과 같이 Data는 따로 넣어줘야 하기 때문에 result.setData를 사용하여 데이터를 넣어줬습니다.
BasicSignupRequestDto
@Getter
@NoArgsConstructor
public class BasicSignupRequestDto {
private String email;
private String password;
private String name;
private String nickname;
private String phoneNumber;
private String gender;
private String profileImgUrl;
private String introduce;
private String provider;
private String zipCode;
private String streetAddress;
private String detailAddress;
@Builder
public BasicSignupRequestDto(String email, String password, String name,
String nickname, String phoneNumber, String gender,
String profileImgUrl, String introduce, String zipCode,
String streetAddress, String detailAddress, String provider) {
this.email = email;
this.password = password;
this.name = name;
this.nickname = nickname;
this.phoneNumber = phoneNumber;
this.gender = gender;
this.profileImgUrl = profileImgUrl;
this.introduce = introduce;
this.zipCode = zipCode;
this.streetAddress = streetAddress;
this.detailAddress = detailAddress;
this.provider = provider;
}
public User toBasicUserEntity() {
return User.builder()
.email(email)
.password(password)
.name(name)
.nickname(nickname)
.phoneNumber(phoneNumber)
.gender(gender)
.profileImgUrl(profileImgUrl)
.introduce(introduce)
.role(Role.USER)
.provider(null)
.build();
}
public Address toAddressEntity(User user) {
return Address.builder()
.zipCode(zipCode)
.streetAddress(streetAddress)
.detailAddress(detailAddress)
.user(user)
.isDefault(true)
.build();
}
}
dto에서 User와 Address 객체로 변환하기 위해 toEntity를 미리 만들어줬습니다.
SignupResponseDto
@Getter
public class SignupResponseDto {
private Long userId;
public SignupResponseDto(Long userId) {
this.userId = userId;
}
}
반환하는 dto입니다.
BasicSugnupService
@RequiredArgsConstructor
@Service
public class BasicSignupService {
private final UserRepository userRepository;
private final AddressRepository addressRepository;
private final CommonService commonService;
private final PasswordEncoder passwordEncoder;
// 자체 회원 가입
@Transactional
public Long basicSignup(BasicSignupRequestDto basicSignupRequestDto) {
userRepository.findByNickname(basicSignupRequestDto.getNickname()).ifPresent(a -> {
throw new IllegalStateException(ErrorCode.NICKNAME_THAT_EXIST);
});
userRepository.findByEmail(basicSignupRequestDto.getEmail()).ifPresent(a -> {
throw new IllegalStateException(ErrorCode.EMAIL_THAT_EXIST);
});
userRepository.findByPhoneNumber(basicSignupRequestDto.getPhoneNumber()).ifPresent(a -> {
throw new IllegalStateException(ErrorCode.PHONE_NUMBER_THAT_EXIST);
});
User user = basicSignupRequestDto.toBasicUserEntity();
user.passwordEncode(passwordEncoder);
Long userId = userRepository.save(user).getId();
Address address = basicSignupRequestDto.toAddressEntity(user);
addressRepository.save(address);
return userId;
}
// API 반환
@Transactional
public CommonResponse<Object> signupResponse(BasicSignupRequestDto basicSignupRequestDto) {
Long userId = basicSignup(basicSignupRequestDto);
return commonService.successResponse(SuccessCode.BASIC_SIGNUP_SUCCESS.getDescription(), HttpStatus.CREATED, new SignupResponseDto(userId));
}
}
서비스 코드에선 닉네임, 휴대폰 번호, 이메일 중복 시 오류를 반환하도록 만들었습니다. 오류는 ExceptionAdvenceController로 한 번에 반환 값을 정리를 했는데 이 부분은 추후에 작성하도록 하겠습니다.
dto에서 만들어둔 toEntity를 사용하여 User 객체를 만들고 DB에 저장을 해준 후 id를 가져와 반환을 해줬습니다.
address도 마찬가지로 DB에 저장을 하는데 각자 테이블이 나누어져 있어서 따로 DB에 저장을 했습니다.
그 후 API 반환 값에 넣어주기 위해 signupResponse를 CommonSerivce로 반환 값을 넣어줬습니다.
CommonService
@Service
public class CommonService {
public CommonResponse<Object> successResponse(String message, HttpStatus httpStatus, Object data) {
return CommonResponse.builder()
.httpStatus(httpStatus)
.status(ResponseStatus.SUCCESS.getDescription())
.message(message)
.data(data)
.build();
}
public CommonResponse<Object> errorResponse(String message, HttpStatus httpStatus, Object data) {
return CommonResponse.builder()
.httpStatus(httpStatus)
.status(ResponseStatus.FAIL.getDescription())
.message(message)
.data(data)
.build();
}
}
CommonService를 사용하여 항상 일정한 반환 값을 넣을 수 있도록 했습니다.
너무 뒤죽박죽 작성이 된 것 같습니다.. 제가 코드를 만들었던 순서대로 작성 중이어서 양해 부탁드립니다.
다음은 로그인에 대해 작성 하도록 하겠습니다.
[Spring Boot]회원 가입 & 로그인 (1)
기본 회원 가입 및 로그인을 구현하면서 소셜 로그인도 같이 병합해서 사용해야겠다는 생각이 들어 만들어 봤습니다. ERD는 쇼핑몰을 생각하면서 만들어 봤습니다. 먼저 기본 회원 가입 ERD 입니
classruntime.tistory.com
GitHub - Llimy1/Auth_Spring
Contribute to Llimy1/Auth_Spring development by creating an account on GitHub.
github.com
'Backend > Spring' 카테고리의 다른 글
[Spring Boot] 회원 가입 & 로그인(5) (0) | 2023.10.04 |
---|---|
[Spring Boot] 회원 가입 & 로그인(4) (1) | 2023.10.04 |
[Spring Boot] 회원 가입 & 로그인(3) (0) | 2023.10.04 |
[Spring Boot]회원 가입 & 로그인 (1) (0) | 2023.09.26 |