Skip to content

[3주차] 임성현/[feat] 게시글 도메인 API 구현#112

Merged
sky-0131 merged 11 commits intoLeets-Official:임성현/mainfrom
sky-0131:임성현/3주차
Apr 14, 2026

Hidden character warning

The head ref may contain hidden characters: "\uc784\uc131\ud604/3\uc8fc\ucc28"
Merged

[3주차] 임성현/[feat] 게시글 도메인 API 구현#112
sky-0131 merged 11 commits intoLeets-Official:임성현/mainfrom
sky-0131:임성현/3주차

Conversation

@sky-0131
Copy link
Copy Markdown

@sky-0131 sky-0131 commented Apr 7, 2026

1. 과제 요구사항 중 구현한 내용

  • 게시글 API 완성: 등록, 목록 조회, 상세 조회, 수정, 삭제 기능 구현
  • 예외 처리: 유효성(400), 권한(403), 미존재(4041)

2. 핵심 변경 사항

  1. Mapper 추가
    PostMapper 클래스 정의: 컨트롤러나 서비스 코드에 로직 섞이지 않도록 분리.
  2. 예외 처리
    ApiExceptionHandler 수정: 비즈니스 예외와 유효성 검사 예외를 공통 처리.
  3. 엔티티 식별자 오류 수정

3. 실행 및 검증 결과

userId 생성

image

post 생성

image

post 조회

image

post 수정

image

목록 조회

image

post 삭제

image

예외 처리 - 게시물 없음

image

예외 처리 - 잘못된 입력값 요청

image

4. 완료 사항

  • 프로젝트 정상 실행 및 빌드 확인.
  • 게시글 목록/상세 조회 시 설계된 DTO 규격대로 출력 확인.
  • 권한 없는 사용자의 수정/삭제 접근 제어 로직 구현.
  • 예외 상황 발생 시 공통 에러 메시지(error, message) 반환 확인

5. 추가 사항

#109

제출 체크리스트

  • PR 제목이 규칙에 맞다
  • base가 {이름}/main 브랜치다
  • compare가 {이름}/{숫자}주차 브랜치다
  • 프로젝트가 정상 실행된다
  • 본인을 Assignee로 지정했다
  • 파트 담당 Reviewer를 지정했다
  • 리뷰 피드백을 반영한 뒤 머지/PR close를 진행한다

@sky-0131 sky-0131 self-assigned this Apr 7, 2026
@sky-0131 sky-0131 changed the title [3주차] 임성/[feat] 게시글 도메인 API 구현 [3주차] 임성현/[feat] 게시글 도메인 API 구현 Apr 7, 2026
Copy link
Copy Markdown
Member

@theSnackOverflow theSnackOverflow left a comment

Choose a reason for hiding this comment

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

Mapper 분리로 엔티티-DTO 변환 로직을 서비스/컨트롤러에서 깔끔하게 빼주신 점이 좋았고, @Transactional(readOnly = true)를 클래스 레벨에 걸고 변경 메서드만 @Transactional로 오버라이드하는 패턴도 적절하게 적용해주셨네요. 목록용/상세용 DTO를 분리해서 필요한 데이터만 노출하는 구조도 잘 잡혀있습니다.

몇 가지 확인해보시면 좋을 것 같은 부분 남겨봅니다!

// 게시글 작성
@PostMapping
public Long createPost(@RequestBody PostRequest requestDto, @RequestParam Long userId) {
return postService.createPost(requestDto, userId);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@RequestBody@Valid가 빠져 있는데요, PostRequest@NotBlank 검증 어노테이션을 잘 달아주셨지만 컨트롤러에서 @Valid가 없으면 유효성 검사가 실제로 실행되지 않습니다. ApiExceptionHandler에서 MethodArgumentNotValidException 처리까지 해두셨으니, @Valid만 추가해주시면 바로 연결될 것 같아요!

public Long createPost(@RequestBody @Valid PostRequest requestDto, ...)

updatePost@RequestBody에도 동일하게 적용해주시면 좋을 것 같아요!


// 서비스 로직 에러 처리 ,403 Forbidden, 404 Not Found
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Map<String, String>> handleRuntimeException(RuntimeException ex) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@ExceptionHandler(RuntimeException.class)로 처리하고 계신데요, 이렇게 하면 NullPointerException이나 IllegalStateException 같은 예상치 못한 런타임 예외까지 모두 이 핸들러에서 잡히게 됩니다. 의도하지 않은 에러가 비즈니스 에러 메시지 형태로 반환될 수 있어서, 커스텀 예외 클래스를 만들어서 사용해보시면 좋을 것 같아요!

public class PostNotFoundException extends RuntimeException { ... }
public class ForbiddenException extends RuntimeException { ... }

@ExceptionHandler(PostNotFoundException.class)
public ResponseEntity<Map<String, String>> handlePostNotFound(...) { ... }

.title(requestDto.getTitle())
.content(requestDto.getContent())
.status(PostStatus.valueOf(requestDto.getStatus()))
.user(user) // 📍 외래키 연결
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

PostStatus.valueOf()로 문자열을 enum으로 변환하고 계신데요, 잘못된 값(예: "HELLO")이 들어오면 IllegalArgumentException이 발생하고, 이것이 RuntimeException 핸들러에 잡혀서 내부 에러 메시지가 그대로 500 응답으로 노출될 수 있습니다. status 필드를 DTO에서 String 대신 PostStatus enum 타입으로 직접 받거나, 변환 전에 별도 검증을 추가해주시면 좋을 것 같아요!

}

post.update(requestDto.getTitle(), requestDto.getContent());
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

updatePost에서 titlecontent만 수정하고 있는데요, PostRequeststatus 필드도 포함되어 있으니 수정 시에도 status 변경이 반영되도록 post.update() 메서드에 status 파라미터를 추가해주시면 좋을 것 같아요!

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/posts")
public class PostController {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

사소한 부분이긴 한데, Post API는 /api/posts, User API는 /api/v1/users로 경로 버전 체계가 다르게 되어 있는데요, 프로젝트 전체에서 일관된 URL 규칙을 사용해주시면 나중에 관리하기 더 편할 것 같아요!

package com.example.blog7th;

import com.example.blog7th.domain.user.User;
import com.example.blog7th.repository.UserRepository;
Copy link
Copy Markdown
Member

@theSnackOverflow theSnackOverflow Apr 9, 2026

Choose a reason for hiding this comment

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

User, UserRepository, CommandLineRunner, @Bean import가 추가되어 있지만 실제로 사용되는 곳이 없는 것 같아요. 혹시 개발 중에 테스트하시다가 남은 건가요? 사용하지 않는 import는 정리해주시면 좋을 것 같아요!

private String content;

// 📍 이 부분을 추가하세요!
@NotBlank(message = "공개 여부는 필수입니다.")
Copy link
Copy Markdown
Member

@theSnackOverflow theSnackOverflow Apr 9, 2026

Choose a reason for hiding this comment

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

개발 중 메모로 보이는 주석이 남아있는 것 같아요. 제출 전에 정리해주시면 좋을 것 같아요!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

매번 리뷰 감사합니다! 현재 달린 리뷰와 관련된 사항을 전부 수정했습니다. 또 추가로 기능별로 파일을 구별하여 정리했습니다.

@daekyochung
Copy link
Copy Markdown

BaseTimeEntity를 활용하여 createdAt, updatedAt을 자동으로 관리하고, GlobalExceptionHandler와 Custom Exception으로 예외처리를 중앙에서 일관성 있게 처리하는 부분이 인상 깊습니다 고생하셨습니다!

@yukyoungs
Copy link
Copy Markdown

전반적으로 계층 분리(Controller-Service-DTO)가 아주 깔끔하게 되어 있네요! 몇 가지 안정성을 높일 수 있는 부분들 의견드릴게요!

@sky-0131 sky-0131 closed this Apr 14, 2026
@sky-0131 sky-0131 reopened this Apr 14, 2026
@sky-0131 sky-0131 merged commit 072972b into Leets-Official:임성현/main Apr 14, 2026
@sky-0131 sky-0131 deleted the 임성현/3주차 branch April 14, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants