Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3주차 심화과제 #5

Open
wants to merge 2 commits into
base: #3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package sopt.org.ThirdSeminar.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import sopt.org.ThirdSeminar.common.dto.ApiResponseDto;
import sopt.org.ThirdSeminar.controller.dto.request.PostRequestDto;
import sopt.org.ThirdSeminar.controller.dto.response.PostResponseDto;
import sopt.org.ThirdSeminar.exception.ErrorStatus;
import sopt.org.ThirdSeminar.exception.SuccessStatus;
import sopt.org.ThirdSeminar.exception.UserNotFoundException;
import sopt.org.ThirdSeminar.service.PostService;

import java.util.List;

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

private final PostService postService;

//게시물 생성
@PostMapping("")
@ResponseStatus(HttpStatus.CREATED)
public ApiResponseDto<PostResponseDto> createPost(@RequestBody final PostRequestDto request) {
try {
return ApiResponseDto.success(SuccessStatus.CREATE_POST_SUCCESS, postService.createPost(request));
} catch (UserNotFoundException e) {
return ApiResponseDto.error(ErrorStatus.USER_NOT_FOUND);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 이 에러 상황일 때 http 응답코드가 어떻게 반환되나요? @ResponseStatus(HttpStatus.CREATED)가 있어도 응답코드가 404로 나올지 궁금합니다!

}
}

//유저아이디로 게시물 조회
@GetMapping("/{userId}")
public ApiResponseDto<List<PostResponseDto>> getPostByUserId(@PathVariable final int userId) {
return ApiResponseDto.success(SuccessStatus.READ_ALL_POST, postService.getPostByUserId((long) userId));
}

//제목으로 게시물 조회
@GetMapping("")
public ApiResponseDto<List<PostResponseDto>> getPostByTitle(@RequestParam final String title) {
return ApiResponseDto.success(SuccessStatus.READ_ALL_POST, postService.getPostByTitle(title));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class UserController {

private final UserService userService;

//* 유저 생성
@PostMapping("/user/signup")
@ResponseStatus(HttpStatus.CREATED)
public ApiResponseDto<UserResponseDto> create(@RequestBody @Valid final UserRequestDto request) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package sopt.org.ThirdSeminar.controller.dto.request;

import lombok.Getter;

import javax.validation.constraints.NotNull;

@Getter
public class PostRequestDto {
@NotNull
private Long userId;
@NotNull
private String title;
private String content;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package sopt.org.ThirdSeminar.controller.dto.response;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class PostResponseDto {
private Long postId;
private String title;
private String content;

public static PostResponseDto of(Long postId, String title, String content) {
return new PostResponseDto(postId, title, content);
}
}
35 changes: 35 additions & 0 deletions ThirdSeminar/src/main/java/sopt/org/ThirdSeminar/domain/Post.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package sopt.org.ThirdSeminar.domain;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
//@Column 생략 가능
private String content;
private LocalDateTime createdAt;

@Builder
public Post(String title, String content, User user) {
this.title = title;
this.content = content;
this.user = user;
this.createdAt = LocalDateTime.now();
}

@ManyToOne(fetch = FetchType.LAZY) //다대일(N:1) 관계
@JoinColumn(name = "user_id") //외래키 매핑
private User user;
}
15 changes: 13 additions & 2 deletions ThirdSeminar/src/main/java/sopt/org/ThirdSeminar/domain/User.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
package sopt.org.ThirdSeminar.domain;

import lombok.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@Column(nullable = false)
private String nickname;
@Column(nullable = false)
private String email;
@Column(nullable = false)
private String password;

@Builder
public User(String nickname, String email, String password) {
this.nickname = nickname;
this.email = email;
this.password = password;
}

//mappedBy 양방향 연관관계 주인 user x -> post(외래키를 가진 쪽)
@OneToMany(mappedBy = "user") //일대다(1:N)
private final List<Post> posts = new ArrayList<>();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

user를 가지고 post에 접근할 일이 없다면 양방향으로 설정하지 않아도 될 것 같아요!

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public enum ErrorStatus {
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "예상치 못한 서버 에러가 발생했습니다."),
BAD_GATEWAY_EXCEPTION(HttpStatus.BAD_GATEWAY, "일시적인 에러가 발생하였습니다.\n잠시 후 다시 시도해주세요!"),
SERVICE_UNAVAILABLE_EXCEPTION(HttpStatus.SERVICE_UNAVAILABLE, "현재 점검 중입니다.\n잠시 후 다시 시도해주세요!"),

/*
User
*/
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "유저가 존재하지 않습니다."),
;

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ public enum SuccessStatus {
/*
user
*/
SIGNUP_SUCCESS(HttpStatus.CREATED, "회원가입이 완료되었습니다."),
SIGNUP_SUCCESS(HttpStatus.CREATED, "유저 생성 성공"),

/*
post
*/
CREATE_POST_SUCCESS(HttpStatus.CREATED, "게시물 작성 성공"),
READ_ALL_POST(HttpStatus.OK, "게시물 조회 성공"),
;

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package sopt.org.ThirdSeminar.exception;

public class UserNotFoundException extends RuntimeException {
public UserNotFoundException() {
super();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package sopt.org.ThirdSeminar.infrastructure;

import org.springframework.data.repository.Repository;
import sopt.org.ThirdSeminar.domain.Post;

import java.util.List;

public interface PostRepository extends Repository<Post, Long> {
void save(Post post);

List<Post> findAllByUserId(Long userId);

List<Post> findAllByTitle(String title);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

public interface UserRepository extends Repository<User, Long> {
void save(User user);

User findById(Long id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package sopt.org.ThirdSeminar.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sopt.org.ThirdSeminar.controller.dto.request.PostRequestDto;
import sopt.org.ThirdSeminar.controller.dto.response.PostResponseDto;
import sopt.org.ThirdSeminar.domain.Post;
import sopt.org.ThirdSeminar.domain.User;
import sopt.org.ThirdSeminar.exception.UserNotFoundException;
import sopt.org.ThirdSeminar.infrastructure.PostRepository;
import sopt.org.ThirdSeminar.infrastructure.UserRepository;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor //final이 붙거나 @NotNull 이 붙은 필드의 생성자를 자동 생성
public class PostService {

private final UserRepository userRepository;
private final PostRepository postRepository;

@Transactional //일련의 작업을 하나로 묶어서 처리 -> 오류가 발생했을 때 모든 작업들을 원상태로 되돌릴 수 있음
public PostResponseDto createPost(PostRequestDto request) {
final Optional<User> user = Optional.ofNullable(userRepository.findById(request.getUserId()));
user.orElseThrow(UserNotFoundException::new);

Post post = Post.builder()
.title(request.getTitle())
.content(request.getContent())
.user(user.get())
.build();

postRepository.save(post);

return PostResponseDto.of(post.getId(), post.getTitle(), post.getContent());
}

public List<PostResponseDto> getPostByUserId(final Long userId) {
final List<PostResponseDto> postList = new ArrayList<>();
postRepository.findAllByUserId(userId).forEach((p) ->
postList.add(PostResponseDto.of(p.getId(), p.getTitle(), p.getContent()))
);
return postList;
}

public List<PostResponseDto> getPostByTitle(final String title) {
final List<PostResponseDto> postList = new ArrayList<>();
postRepository.findAllByTitle(title).forEach((p) ->
postList.add(PostResponseDto.of(p.getId(), p.getTitle(), p.getContent()))
);
return postList;
}
}