지난 포스팅에 생성한 스프링 부트 애플리케이션에 게시판을 생성해보자
@AllArgsConstructor
@Getter
public class BaseResponse {
@JsonProperty("isSuccess")
boolean isSuccess;
String message;
Object data;
}
@RestController
@RequiredArgsConstructor
@RequestMapping("/post")
public class PostController {
private final PostService postService;
@GetMapping("/list")
@ResponseStatus(HttpStatus.OK)
public ResponseEntity<BaseResponse> getPostList(
Pageable pageable
) {
return ResponseEntity.ok(new BaseResponse(true, "", postService.getPostList(pageable)));
}
@PostMapping
public ResponseEntity<BaseResponse> createPost(
@RequestBody PostDto post
) {
if (post.getTitle() == null || post.getTitle().isBlank()) {
return ResponseEntity.badRequest().body(new BaseResponse(false, "제목은 필수입력 항목입니다.", null));
}
if (post.getContent() == null || post.getContent().isBlank()) {
return ResponseEntity.badRequest().body(new BaseResponse(false, "내용은 필수입력 항목입니다.", null));
}
return ResponseEntity.ok(new BaseResponse(true, "", postService.createPost(post)));
}
@GetMapping("/{id}")
public ResponseEntity<BaseResponse> getPostById(
@PathVariable(name = "id") String id
) {
PostDto post = postService.getPostById(Long.valueOf(id));
if (post == null) {
return ResponseEntity.badRequest().body(new BaseResponse(false, "유효하지 않은 id입니다.", null));
}
return ResponseEntity.ok(new BaseResponse(true, "", post));
}
@PatchMapping
public ResponseEntity<BaseResponse> updatePost(
@RequestBody PostDto post
) {
if (post.getId() == null || post.getId() < 0) {
return ResponseEntity.badRequest().body(new BaseResponse(false, "유효하지 않은 id입니다.", null));
}
if (post.getTitle() == null || post.getTitle().isBlank()) {
return ResponseEntity.badRequest().body(new BaseResponse(false, "제목은 필수입력 항목입니다.", null));
}
if (post.getContent() == null || post.getContent().isBlank()) {
return ResponseEntity.badRequest().body(new BaseResponse(false, "내용은 필수입력 항목입니다.", null));
}
PostDto target = postService.getPostById(post.getId());
if (target == null) {
return ResponseEntity.badRequest().body(new BaseResponse(false, "유효하지 않은 게시물입니다.", null));
}
PostDto updatedPost = postService.updatePost(post);
return ResponseEntity.ok(new BaseResponse(true, "", updatedPost));
}
@DeleteMapping("/{id}")
public ResponseEntity<BaseResponse> deletePost(
@PathVariable(name = "id") String id
) {
PostDto post = postService.getPostById(Long.valueOf(id));
if (post == null) {
return ResponseEntity.badRequest().body(new BaseResponse(false, "유효하지 않은 id입니다.", null));
}
postService.deletePost(Long.valueOf(id));
Map<String, String> result = Map.of("deletedPost", id);
return ResponseEntity.ok(new BaseResponse(true, "", result));
}
}
public interface PostService {
List<PostDto> getPostList(Pageable pageable);
PostDto createPost(PostDto post);
PostDto getPostById(Long id);
PostDto updatePost(PostDto post);
void deletePost(Long id);
}
@Service
@RequiredArgsConstructor
@Transactional
public class PostServiceImpl implements PostService {
private final PostRepository postRepository;
@Override
public List<PostDto> getPostList(Pageable pageable) {
return postRepository.findAll(pageable).stream().map(PostEntity::toDto).toList();
}
@Override
public PostDto createPost(PostDto post) {
return postRepository.save(post.toEntity()).toDto();
}
@Override
public PostDto getPostById(Long id) {
return postRepository.findById(id).map(PostEntity::toDto).orElse(null);
}
@Override
public PostDto updatePost(PostDto post) {
return postRepository.save(post.toEntity()).toDto();
}
@Override
public void deletePost(Long id) {
postRepository.deleteById(id);
}
}
public interface PostRepository extends JpaRepository<PostEntity, Long> {
}
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table
public class PostEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false, updatable = false)
private Long id;
@Column(name = "title", nullable = false, length = 100)
private String title;
@Column(name = "content", nullable = false, columnDefinition = "TEXT")
private String content;
@Column(name = "created_at", nullable = false, updatable = false)
@CreatedDate
private LocalDateTime createdAt;
@Builder.Default
@Column(name = "updated_at")
@LastModifiedDate
private LocalDateTime updatedAt = null;
@PrePersist
public void prePersist() {
this.createdAt = LocalDateTime.now();
}
@PreUpdate
public void preUpdate() {
this.updatedAt = LocalDateTime.now();
}
public PostDto toDto() {
return PostDto.builder()
.id(id)
.title(title)
.content(content)
.createdAt(createdAt)
.updatedAt(updatedAt)
.build();
}
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PostDto {
private Long id;
private String title;
private String content;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
public PostEntity toEntity() {
return PostEntity.builder()
.id(id)
.title(title)
.content(content)
.createdAt(createdAt)
.updatedAt(updatedAt)
.build();
}
}
마지막으로 application.properties
에 아래 코드를 추가한다.
... 생략
spring.jpa.hibernate.ddl-auto=create
위 코드를 추가하면 @Entity
어노테이션이 붙은 클래스와 대칭되는 테이블을 데이터베이스에 자동 생성해준다.
POST
요청 GET
요청 (단건)GET
요청 (다건)PATCH
요청DELETE
요청모든 요청에 정상 응답이 반환 된다.
이번엔 에러 처리가 정상적으로 이뤄 지는지 확인해보자.
GET
요청POST
요청POST
요청PATCH
요청PATCH
요청PATCH
요청DELETE
요청에러 처리가 정상적으로 이뤄졌다.