전체 스택 Reddit 클론 - Spring Boot, React, Electron 앱 - 8부

전체 스택 Reddit 클론 - Spring Boot, React, Electron 앱 - 8부



소개



Spring Boot 및 React를 사용하여 Reddit 클론 생성의 8부에 오신 것을 환영합니다.

이 부분에서 우리는 무엇을 만들고 있습니까?
  • 투표 DTO
  • 투표 예외
  • 투표 서비스
  • 투표 컨트롤러

  • 댓글을 작성하고 읽기 위한 CREATE && READ 끝점을 추가했습니다!!

    중요한 링크


  • 백엔드 소스: https://github.com/MaxiCB/vox-nobis/tree/master/backend
  • 프런트엔드 소스: https://github.com/MaxiCB/vox-nobis/tree/master/client
  • 실시간 URL: 진행 중

  • 파트 1: DTO 투표 📨



    투표 정보를 수신하고 전송하는 데 필요한 DTO를 다루겠습니다. com.your-name.backend.dto 내부에 다음 클래스를 생성합니다.
  • VoteDTO: 클라이언트에서 API로 보낼 데이터 생성을 처리합니다.

  • 
    import com.maxicb.backend.model.VoteType;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class VoteDTO {
        private VoteType voteType;
        private Long id;
    }
    


    파트 2: 투표 예외 🚫



    필요한 사용자 정의 예외를 다루겠습니다. com.your-name.backend.exception 안에 다음 클래스를 생성합니다.
  • VoteException: 잘못된 사용자 찾기와 관련된 예외를 처리합니다.

  • package com.maxicb.backend.exception;
    
    public class VoteException extends RuntimeException {
            public VoteException(String message) {
                super(message);
            }
    }
    
    


    3부: 투표 서비스 🌎



    애플리케이션이 갖게 될 투표 서비스를 다루겠습니다. com.your-name.backend.services 내부에 다음 클래스를 추가합니다.
  • VoteService: 데이터를 DTO와 매핑하고 게시물에 투표를 추가하기 위한 논리를 유지합니다.

  • package com.maxicb.backend.service;
    
    import com.maxicb.backend.dto.VoteDTO;
    import com.maxicb.backend.exception.PostNotFoundException;
    import com.maxicb.backend.model.Post;
    import com.maxicb.backend.model.Vote;
    import com.maxicb.backend.repository.PostRepository;
    import com.maxicb.backend.repository.VoteRepository;
    import lombok.AllArgsConstructor;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.Optional;
    
    import static com.maxicb.backend.model.VoteType.UPVOTE;
    
    @Service
    @AllArgsConstructor
    public class VoteService {
        private final VoteRepository voteRepository;
        private final PostRepository postRepository;
        private final AuthService authService;
    
        private Vote maptoVote(VoteDTO voteDTO, Post post) {
            return Vote.builder()
                    .voteType(voteDTO.getVoteType())
                    .post(post)
                    .user(authService.getCurrentUser())
                    .build();
        }
    
        @Transactional
        public void vote(VoteDTO voteDTO) {
            Post post = postRepository.findById(voteDTO.getId())
                    .orElseThrow(() -> new PostNotFoundException("Post not found with id:" + voteDTO.getId()));
            Optional<Vote> votePostAndUser = voteRepository.findTopByPostAndUserOrderByVoteIdDesc(post, authService.getCurrentUser());
            if(votePostAndUser.isPresent() && votePostAndUser.get().getVoteType().equals(voteDTO.getVoteType())) {
                throw new PostNotFoundException("You've already " + voteDTO.getVoteType() + "'d this post");
            }
            if(UPVOTE.equals(voteDTO.getVoteType())) {
                post.setVoteCount(post.getVoteCount() + 1);
            } else {
                post.setVoteCount(post.getVoteCount() - 1);
            }
            voteRepository.save(maptoVote(voteDTO, post));
            postRepository.save(post);
        }
    }
    


    파트 4: 투표 컨트롤러 🌐



    우리 애플리케이션이 가질 투표 컨트롤러를 다루겠습니다. com.your-name.backend.controller 내부에 다음 클래스를 추가합니다.
  • VoteController: 특정 게시물에 투표를 추가하는 끝점을 유지합니다.

  • package com.maxicb.backend.controller;
    
    import com.maxicb.backend.dto.VoteDTO;
    import com.maxicb.backend.service.VoteService;
    import lombok.AllArgsConstructor;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/api/vote")
    @AllArgsConstructor
    public class VoteController {
    
        private final VoteService voteService;
    
        @PostMapping
        public ResponseEntity<Void> vote(@RequestBody VoteDTO voteDTO) {
            voteService.vote(voteDTO);
            return new ResponseEntity<>(HttpStatus.OK);
        }
    }
    


    결론 🔍


  • 모든 것이 올바르게 구성되었는지 확인하려면 응용 프로그램을 실행하고 콘솔에 오류가 없는지 확인할 수 있습니다. 콘솔 하단을 향해 아래와 유사한 출력이 표시되어야 합니다
  • .


  • 콘솔에 오류가 없으면 다음 데이터와 함께 http://localhost:8080/api/vote에 게시 요청을 전송하여 투표 로직을 테스트할 수 있습니다. 포스트를 만들기 위해 계정에 로그인하고 하위 레딧을 만들고 댓글을 추가할 유효한 포스트를 만들기 위해 이전 파트에서 다룬 것과 동일한 단계를 따라야 합니다.

  • {
        "voteType": "UPVOTE",
        "id": <post-id>
    }
    


  • 이제 http://localhost:8080/api/posts/에 GET 요청을 보내 방금 업보팅한 게시물의 voteCount 변경 사항을 확인할 수 있습니다.

  • {
        "postId": 9,
        "postTitle": "Testing Post",
        "url": "URL",
        "description": "DESCRIPTION",
        "userName": "USERNAME",
        "subredditName": "/r/NAME",
        "voteCount": 1,
        "commentCount": 1,
        "duration": "4 hours ago",
        "upVote": true,
        "downVote": false
    }
    


  • 이 문서에서는 게시물의!에 대한 투표 논리를 구현했습니다.

  • 다음



    게시물 투표 기능을 다룰 파트 9가 출시될 때 알림을 받으려면 팔로우하세요! 질문이 있으시면 댓글을 남겨주세요!

    좋은 웹페이지 즐겨찾기