개발/🍐 배울림꽃

🍐 [이화톤] 배울림꽃 - 이화 청원 프로그램 리팩토링( 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()에 넣어서 로직 수행