Full Stack Reddit Clone – Spring Boot, React, Electron App – Part 8

Full Stack Reddit Clone – Spring Boot, React, Electron App – Part 8

Introduction

Welcome to Part 8 of creating a Reddit clone using Spring Boot, and React.

What are we building in this part?

Vote DTO
Vote Exception
Vote Service…


This content originally appeared on DEV Community and was authored by Aaron C. Beasley

Full Stack Reddit Clone - Spring Boot, React, Electron App - Part 8

Introduction

Welcome to Part 8 of creating a Reddit clone using Spring Boot, and React.

What are we building in this part?

  • Vote DTO
  • Vote Exception
  • Vote Service
  • Vote Controller

In Part 7 we added the CREATE && READ endpoints for creating and reading comments!!

Important Links

Part 1: Vote DTO ?

Let's cover our the DTO's we will need for receiving and sending Vote information. Inside com.your-name.backend.dto we will create the following class.

  • VoteDTO: Handles creation of the data that will be sent from the client to the 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;
}

Part 2: Vote Exception ?

Let's cover our custom exceptions we will need. Inside com.your-name.backend.exception we will create the following class.

  • VoteException: Handles exceptions related to looking for a invalid user.
package com.maxicb.backend.exception;

public class VoteException extends RuntimeException {
        public VoteException(String message) {
            super(message);
        }
}

Part 3: Vote Service ?

Let's cover the vote service our application will have. Inside com.your-name.backend.services add the following class.

  • VoteService: Hold the logic for mapping data to and from DTO's, and adding votes to a post.
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);
    }
}

Part 4: Vote Controller ?

Let's cover the vote controller our application will have. Inside com.your-name.backend.controller add the following class.

  • VoteController: Hold the endpoints adding votes to a specific post.
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);
    }
}

Conclusion ?

  • To ensure everything is configured correctly you can run the application, and ensure there are no error in the console. Towards the bottom of the console you should see output similar to below

Alt Text

  • If there are no error's in the console you can test the voting logic by sending a post request to http://localhost:8080/api/vote with the following data. You will still have to follow the same steps covered in the previous parts to login to an account to make post's, as well as create a subreddit, and valid post to add a comment to.
{
    "voteType": "UPVOTE",
    "id": <post-id>
}
{
    "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
}
  • In this article we implemented the logic for voting on post's!.

Next

Follow to get informed when part nine is released, where we will cover the post voting functionality! If you have any questions be sure to leave a comment!


This content originally appeared on DEV Community and was authored by Aaron C. Beasley


Print Share Comment Cite Upload Translate Updates
APA

Aaron C. Beasley | Sciencx (2021-03-10T04:38:38+00:00) Full Stack Reddit Clone – Spring Boot, React, Electron App – Part 8. Retrieved from https://www.scien.cx/2021/03/10/full-stack-reddit-clone-spring-boot-react-electron-app-part-8/

MLA
" » Full Stack Reddit Clone – Spring Boot, React, Electron App – Part 8." Aaron C. Beasley | Sciencx - Wednesday March 10, 2021, https://www.scien.cx/2021/03/10/full-stack-reddit-clone-spring-boot-react-electron-app-part-8/
HARVARD
Aaron C. Beasley | Sciencx Wednesday March 10, 2021 » Full Stack Reddit Clone – Spring Boot, React, Electron App – Part 8., viewed ,<https://www.scien.cx/2021/03/10/full-stack-reddit-clone-spring-boot-react-electron-app-part-8/>
VANCOUVER
Aaron C. Beasley | Sciencx - » Full Stack Reddit Clone – Spring Boot, React, Electron App – Part 8. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/03/10/full-stack-reddit-clone-spring-boot-react-electron-app-part-8/
CHICAGO
" » Full Stack Reddit Clone – Spring Boot, React, Electron App – Part 8." Aaron C. Beasley | Sciencx - Accessed . https://www.scien.cx/2021/03/10/full-stack-reddit-clone-spring-boot-react-electron-app-part-8/
IEEE
" » Full Stack Reddit Clone – Spring Boot, React, Electron App – Part 8." Aaron C. Beasley | Sciencx [Online]. Available: https://www.scien.cx/2021/03/10/full-stack-reddit-clone-spring-boot-react-electron-app-part-8/. [Accessed: ]
rf:citation
» Full Stack Reddit Clone – Spring Boot, React, Electron App – Part 8 | Aaron C. Beasley | Sciencx | https://www.scien.cx/2021/03/10/full-stack-reddit-clone-spring-boot-react-electron-app-part-8/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.