개발/🍐 배울림꽃
🍐 [이화톤] 배울림꽃 - 이화 청원 프로그램 리팩토링( 3 ) 청원 - 이메일, 정보 동의 / 청원 내용 기입 API 분리
정소은
2024. 9. 21. 16:17
Post쪽 개발을 끝내고 다시 피그마를 살펴보니까
청원 내용(청원 제목, 내용, 카테고리 등)을 기입하는 페이지랑 청원자 이메일, 정보 동의 받는 페이지가 분리되어 있었다
나는 두 페이지를 하나의 API로 개발했는데
이 개발 방식이 기획 의도랑 맞지 않고 보안적인 측면에서도 좋지 않을 것 같아서
API를 분리해야겠다고 생각했다
🚩 Post 로직
이메일과 정보 동의 받기
-> 이메일 정보가 비어있거나 정보 동의를 하지 않은 경우 예외 발생시키기
이메일 정보, 정보 동의 여부 세션에 저장
청원 내용 기입받기
-> 세션에 저장되어 있던 이메일 정보 가져오기
-> 청원 내용 받기
PostRequestDto
public class PostRequestDto {
@Getter
public static class PostCreateDto {
private String email;
private Boolean infoAgree;
private String title;
private String content;
private Categrory categrory;
List<String> urlList;
public void setEmail(String email) {
this.email = email;
}
public void setInfoAgree(Boolean infoAgree) {
this.infoAgree = infoAgree;
}
}
@Getter
public static class PostPreDto {
private String email;
private Boolean infoAgree;
}
}
PostResponseDto
public class PostResponseDto {
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class PostDto {
private Long postId;
private Member writer;
private Status status;
private String title;
private String content;
private Categrory categrory;
private Integer voteCount;
private LocalDateTime createdDate;
private LocalDateTime deadline;
private Duration dDay;
List<String> urlList;
}
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class PostPreDto {
private String email;
private Boolean infoAgree;
}
}
PostConverter
@Component
@RequiredArgsConstructor
public class PostConverter {
public Post toPostEntity(PostRequestDto.PostCreateDto request) {
//작성자 정보 불러오기(이름만 필요)
Post post = Post.builder()
//.writer(writer)
.email(request.getEmail())
.infoAgree(request.getInfoAgree())
.title(request.getTitle())
.content(request.getContent())
.categrory(request.getCategrory())
.build();
post.updateUrlList(request.getUrlList());
return post;
}
public PostResponseDto.PostDto toPostDto(Post post) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime createdDate = post.getCreatedDate();
LocalDateTime deadline = createdDate.plusDays(10);
Duration dDay = Duration.between(deadline, now);
PostResponseDto.PostDto postDto = PostResponseDto.PostDto.builder()
.postId(post.getPostId())
.status(post.getStatus())
.writer(post.getWriter())
.title(post.getTitle())
.content(post.getContent())
.categrory(post.getCategrory())
.voteCount(post.getVoteCount())
.createdDate(createdDate)
.deadline(deadline)
.dDay(dDay)
.urlList(post.fetchUrlList())
.build();
return postDto;
}
}
수정된 부분
- PostRequestDto.PostPreDto, PostResponseDto.PostPreDto 생성
: email, infoAgree
- PostRequestDto.PostCreateDto에 email, infoAgree setter 생성
: 세션에서 email, infoAgree 받아와서 저장 (dto에 setter 넣는 게 좀 걸림...)
- PostResponseDto.PostDto에서 email 삭제
: 피그마에 email 정보 없길래
- PostConverter
: 수정된 DTO에 맞게 변경
PostService
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class PostService {
private final PostConverter postConverter;
private final PostRepository postRepository;
@Transactional
public PostResponseDto.PostDto createPost(PostRequestDto.PostCreateDto request) {
Post post = postConverter.toPostEntity(request);
postRepository.save(post);
PostResponseDto.PostDto postDto = postConverter.toPostDto(post);
return postDto;
}
public PostResponseDto.PostPreDto prePost(PostRequestDto.PostPreDto request) {
String email = request.getEmail();
Boolean infoAgree = request.getInfoAgree();
if (email == null || email.isEmpty()) {
throw new GeneralException(ErrorStatus.EMAIL_REQUIRED);
}
if (infoAgree == null || !infoAgree) {
throw new GeneralException(ErrorStatus.AGREE_REQUIRED);
}
PostResponseDto.PostPreDto postPreDto = new PostResponseDto.PostPreDto(email, infoAgree);
return postPreDto;
}
public Post findById(Long postId){
return postRepository.findById(postId).orElseThrow(()->new GeneralException(ErrorStatus.POST_NOT_FOUND));
}
public PostResponseDto.PostDto getPostDetail(Long postId){
Post post = findById(postId);
PostResponseDto.PostDto postDto = postConverter.toPostDto(post);
return postDto;
}
}
수정된 부분
- prePost() 생성
: email이랑 infoAgree 받아서 이메일이 null인 경우, 정보 동의하지 않은 경우 예외 처리
: PostPreDto 생성
PostController
@RestController
@RequiredArgsConstructor
@RequestMapping("/posts")
public class PostController {
private final PostService postService;
@PostMapping("/pre")
public ApiResponse<PostResponseDto.PostPreDto> prePost(@RequestBody @Valid PostRequestDto.PostPreDto request, HttpSession session) {
session.setAttribute("email", request.getEmail());
session.setAttribute("infoAgree", request.getInfoAgree());
return ApiResponse.onSuccess(postService.prePost(request));
}
@PostMapping("")
public ApiResponse<PostResponseDto.PostDto> createPost(@RequestBody @Valid PostRequestDto.PostCreateDto request, HttpSession session) {
String email = (String)session.getAttribute("email");
Boolean infoAgree = (Boolean)session.getAttribute("infoAgree");
request.setEmail(email);
request.setInfoAgree(infoAgree);
return ApiResponse.onSuccess(postService.createPost(request));
}
@GetMapping("")
public ApiResponse<PostResponseDto.PostDto> getPostDetail(@RequestParam Long postId) {
return ApiResponse.onSuccess(postService.getPostDetail(postId));
}
}
수정된 부분
- /posts/pre 로직 생성
: PostPreDto를 request로 받고 prePost()에 넣어서 예외 처리 및 DTO 생성하도록 함
: email, infoAgree 정보를 세션에 저장
- /posts 로직 변경
: PostCreateDto를 request로 받음
: 세션에 저장된 email, infoAgree 정보 가져와서 PostCreateDto(request)에 저장
: 변경된 request 정보를 createPost()에 넣어서 로직 수행