Skip to content

Commit

Permalink
Merge pull request #28 from 2024-pre-onboarding-backend-F/feat/posts_…
Browse files Browse the repository at this point in the history
…like

[feat] 게시물 좋아요 기능 구현
  • Loading branch information
rhaehf authored Aug 26, 2024
2 parents c78da78 + 712d6ad commit 3cf7a40
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 9 deletions.
15 changes: 15 additions & 0 deletions src/main/java/wanted/media/exception/CustomException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package wanted.media.exception;

import lombok.Getter;

@Getter
public class CustomException extends RuntimeException {
private final ErrorCode errorCode;
private String customMessage;

public CustomException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
this.customMessage = errorCode.getMessage();
}
}
13 changes: 7 additions & 6 deletions src/main/java/wanted/media/exception/ErrorCode.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package wanted.media.exception;

import org.springframework.http.HttpStatus;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;

@Getter
@RequiredArgsConstructor
public enum ErrorCode {
ENTITY_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 엔티티입니다."),
INVALID_PARAMETER(HttpStatus.BAD_REQUEST, "잘못된 요청입니다.");
ENTITY_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 엔티티입니다."),
// 클라이언트의 입력 값에 대한 일반적인 오류 (@PathVariable, @RequestParam가 잘못되었을 때)
INVALID_INPUT_VALUE(HttpStatus.BAD_REQUEST, "클라이언트의 입력 값을 확인해주세요."),
INVALID_PARAMETER(HttpStatus.BAD_REQUEST, "잘못된 요청입니다.");

private final HttpStatus status;
private final String message;
private final HttpStatus status;
private final String message;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import wanted.media.exception.CustomException;
import wanted.media.exception.ErrorCode;
import wanted.media.exception.ErrorResponse;
import wanted.media.exception.NotFoundException;
Expand All @@ -17,7 +18,7 @@ public ResponseEntity<ErrorResponse> handleBadRequestException(BadRequestExcepti
return ResponseEntity.badRequest()
.body(new ErrorResponse(400, e.getMessage()));
}

@ExceptionHandler(NotFoundException.class)
public ResponseEntity<ErrorResponse> handlePostNotFound(NotFoundException e) {
ErrorCode errorCode = e.getErrorCode();
Expand All @@ -27,4 +28,11 @@ public ResponseEntity<ErrorResponse> handlePostNotFound(NotFoundException e) {
);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse);
}

@ExceptionHandler(CustomException.class)
protected ResponseEntity<ErrorResponse> handleCustomException(final CustomException e) {
return ResponseEntity
.status(e.getErrorCode().getStatus().value())
.body(new ErrorResponse(e.getErrorCode().getStatus().value(), e.getCustomMessage()));
}
}
18 changes: 17 additions & 1 deletion src/main/java/wanted/media/post/controller/PostController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import wanted.media.post.domain.Post;
import wanted.media.post.dto.PostDetailResponse;
import wanted.media.post.dto.PostIdResponse;
import wanted.media.post.service.PostService;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/posts")
@RequiredArgsConstructor
public class PostController {

private final PostService posetService;

/**
Expand All @@ -41,4 +45,16 @@ public ResponseEntity<PostDetailResponse> getPost(@PathVariable String postId) {
.build();
return ResponseEntity.ok(result);
}

@PostMapping("/likes/{postId}")
public ResponseEntity<?> getLikes(@PathVariable(name = "postId") String postId) {
try {
String id = postService.increaseLike(postId);
return ResponseEntity.ok().body(new PostIdResponse<>(id, "좋아요 수 증가 완료"));
} catch (Exception e) {
Map<String, String> errorMessage = new HashMap<>();
errorMessage.put("좋아요 수 증가 실패", e.getMessage());
return ResponseEntity.internalServerError().body(new PostIdResponse<>(postId, errorMessage));
}
}
}
6 changes: 6 additions & 0 deletions src/main/java/wanted/media/post/domain/Post.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package wanted.media.post.domain;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;
Expand Down Expand Up @@ -32,6 +33,7 @@ public class Post {
private String title;

private String content;

private String hashtags;

@ColumnDefault("0")
Expand Down Expand Up @@ -59,4 +61,8 @@ public void incrementViewCount() {
}
this.viewCount += 1;
}

public void addLikeCount() {
this.likeCount++;
}
}
11 changes: 11 additions & 0 deletions src/main/java/wanted/media/post/dto/PostIdResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package wanted.media.post.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class PostIdResponse<T> {
private final String postId;
private final T messgae;
}
48 changes: 47 additions & 1 deletion src/main/java/wanted/media/post/service/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import wanted.media.exception.CustomException;
import wanted.media.exception.ErrorCode;
import wanted.media.exception.NotFoundException;
import wanted.media.post.domain.Post;
Expand All @@ -12,7 +13,7 @@
@RequiredArgsConstructor
public class PostService {
private final PostRepository postRepository;

@Transactional
public Post getPost(String postId) {
Post post = postRepository.findById(postId)
Expand All @@ -21,4 +22,49 @@ public Post getPost(String postId) {
post.incrementViewCount();
return post;
}

@Transactional
public String increaseLike(String postId) {
if (postId == null) {
new CustomException(ErrorCode.INVALID_INPUT_VALUE);
}

// contentId를 통해 게시물의 SNS 유형 조회
Post post = postRepository.findById(postId).orElseThrow(() -> new CustomException(ErrorCode.ENTITY_NOT_FOUND));

String snsType = post.getType().name();
// 외부 SNS API 호출 부분 (기능 개발을 위한 요소로, 실제 동작하지 않음)
snsApi(snsType, postId);

// 좋아요 수 증가
post.addLikeCount();
return postId;
}

// 외부 SNS API 호출 부분 (기능 개발을 위한 요소로, 실제 동작하지 않음)
public void snsApi(String snsType, String postId) {
String endpoint = "";

// SNS 유형에 따른 외부 엔드포인트 구성
switch (snsType.toLowerCase()) {
case "facebook":
endpoint = "https://www.facebook.com/likes/" + postId;
break;
case "twitter":
endpoint = "https://www.twitter.com/likes/" + postId;
break;
case "instagram":
endpoint = "https://www.instagram.com/likes/" + postId;
break;
case "threads":
endpoint = "https://www.threads.net/likes/" + postId;
break;
default:
endpoint = null;
}

// 요구사항 시나리오에 따라 필요하지만 실제 동작하지 않기에 주석 처리함
// RestTemplate restTemplate = new RestTemplate();
// String response = restTemplate.postForObject(endpoint, null, String.class);
}
}

0 comments on commit 3cf7a40

Please sign in to comment.