본문 바로가기
Study in Bootcamp/Main Project

[Main Project] Day 5 + 주말 : 회원 관련 CRUD 구현, Rest Docs 시도...

by Bhinney 2022. 11. 14.

본 글은 프로젝트를 기록하기 위해 적은 글 입니다.

수정이 될 수 있으며, 정확하지 않을 수 있습니다.


✅ 주말동안 한 일


📌 연관 관계 매핑

  • 이번에는 많은 테이블이 연관이 되어있다.
  • 그래서 해당 클래스들 중 현제 구현된 엔티티끼리 연관 관계 작업을 해주었다.
  • 일대다, 일대일 매핑과 연관관계 편의 메서드를 사용하여 작업.
  • 생각보다 저번 프리 때에 예시로 적어둔 글이 유용했다.

📌 회원 가입 구현 (Member Create)

  • 입력 되는 권한에 따라 소비자와 판매자를 나눠 역할을 부여하였다.
  • 나중에 시큐리티로 권한을 확인할 역할(roles) 외에 DB에 저장하는 역할도 role로 설정해주었다.


📌 판매자와 소비자의 정보 조회 구현 (Member Read)

  • 판매자의 마이페이지와 소비자의 마이페이지를 조회하는 로직을 구현하였다.
  • 해당 조회는 각 역할(Seller, Client)의 컨트롤러에서 조회하여 해당 컨트롤러들을 만들어 주었다.


📌 판매자와 소비자의 수정 구현 (Member Update)

  • 판매자의 마이페이지와 소비자의 마이페이지에서 각자 수정하는 로직을 구현하였다.
  • 하나의 서비스에서 작업하고 싶었는데, 아직 해당 능력 부족이라 Member와 각 역할의 서비스에서 작업하였다.
  • 각각 역할(Seller, Client)의 서비스에 접근하고 MemberService에 한 번 접근하였다.
  • 아래는 해당 역할 중 클라이언트의 예시 코드이다.
  • Builder도 사용해보았는데, 개인적으로 MapStruct가 깔끔해서 해당 기능으로 구현하였다.
@PatchMapping("/{client_id}")
public ResponseEntity patchClient(@PathVariable("client_id") @Positive long clientId,
		@RequestBody ClientPatchDto clientPatchDto) {

	Client client = clientService.updateClient(clientId, mapper.clientPatchDtoToClient(clientPatchDto));
	long memberId = client.getMember().getMemberId();
	Member member = memberService.updateMember(memberId, mapper.clientPatchDtoToMember(clientPatchDto));

	return ResponseEntity.ok(mapper.memberToClientDto(member, client));
}


📌 회원 삭제 (Member Delete)

  • 프리 프로젝트와는 다르게 이번에는 회원 탈퇴 시 DB에서 아예 삭제해버리기로 했다.
  • 따라서 상태를 변경하던 전과 다르게, 그냥 Repository의 delete Method를 사용하였다.

 

왼쪽은 삭제 전, 오른쪽은 삭제 후


✅ 오늘 한 작업


📌 코드 리팩토링

  • 주말동안 한 로직은 그저 기능 구현에 초점을 맞추고 작업을 하였다.
  • 그래서 컨트롤러에서 예외를 던지고, 많은 작업을 하는 로직이었다.
  • 해당 코드들을 Service 단으로 이동시켜 컨트롤러의 코드를 리팩토링하였다.
/* 전 */
@PatchMapping("/{client_id}")
public ResponseEntity patchClient(@PathVariable("client_id") @Positive long clientId,
		@RequestBody ClientPatchDto clientPatchDto) {
	if (clientId != clientPatchDto.getClientId()) {
		throw new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND);
	}

	/* 현재는 소비자의 역할이 없으므로 따로 서비스를 만들지 않음. */
	Client client = clientService.findVerifiedClient(clientId);
	long memberId = client.getMember().getMemberId();
	Member member = memberService.updateMember(memberId, mapper.clientPatchDtoToMember(clientPatchDto));
	MemberDto.ClientDto response = mapper.memberToClientDto(member, client);

	return ResponseEntity.ok(response);
}

/* 후 */

// Controller
@PatchMapping("/{client_id}")
public ResponseEntity patchClient(@PathVariable("client_id") @Positive long clientId,
		@RequestBody ClientPatchDto clientPatchDto) {

	Client client = clientService.updateClient(clientId, mapper.clientPatchDtoToClient(clientPatchDto));
	long memberId = client.getMember().getMemberId();
	Member member = memberService.updateMember(memberId, mapper.clientPatchDtoToMember(clientPatchDto));

	return ResponseEntity.ok(mapper.memberToClientDto(member, client));
}

// Service
@Transactional(readOnly = true)
public Client updateClient(long clientId, Client client) {
	correctClient(clientId, client.getClientId());
	Client findClient = findVerifiedClient(client.getClientId());

	return clientRepository.save(findClient);
}

public void correctClient(long clientId, long getId) {
	if (clientId != getId) {
		throw new RuntimeException("회원 정보를 확인하세요.");
	}
}

📌 Rest Docs 시도

  • Rest Docs : Spring으로 개발한 REST API를 자동으로 문서화 해주는 도구
  • 문제의 발생 : Response Body가 null 값으로 계속 나옴.
  • 시도해 본 것
    1.  Builder로 아예 ResponseDto를 받아봄 -> 해당 DTO는 생성되지만 Response Body는 여전히 없음.
    2. MapStruct로 만든 로직을 Default로 수정해 봄 -> 제대로 안된 건지 여전히 Response Body는 없음.
    3. Request, ResponseDto, ResponseBody를 모두 출력해보았으나, Response Body만 존재하지 않음.
  •  Request는 문서화가 잘 되었으나 Response가 잘 안됨.
  • 예상 되는 이유 : Mapper에서 각자 역할과 회원 두개의 인자를 가지고 있어서 해당 문제라고 생각됨.
  • 내일 할 일을 마치고 MapperImple를 다시 만들어 보고 그래도 되지 않는다면, 멘토님 찬스를 써야하지 않을까..

📌 JWT Provider 공부

  • 이번에는 꼭 자체 로그인과 소셜로그인을 같이 구현하고 싶다.
  • 그러면 Tokenizer보다 조금 더 Custom이 가능한 Provider가 낫지 않을까 하는 의견을 팀원 분이 내주셨다.
  • 그래서 오늘 해당 클래스에 대해서 조금 검색해보고 공부해보았다.
  • Tokenizer보다는 어색하지만 그래도 쳐보면서 확인해보려고 한다.

🔥내일 할 일

  • 자체 로그인을 위한 JWT Provider 구현
  • UserDetails를 상속받은 MemberPrincipal 혹은 MemberDetails 구현
  • 또한 MemberDetailService도 구현해보기

댓글