Skip to content

[3주차] 남유정/[feat] 게시글 도메인 API 구현#100

Open
N-yujeong wants to merge 3 commits intoLeets-Official:남유정/mainfrom
N-yujeong:남유정/3주차

Hidden character warning

The head ref may contain hidden characters: "\ub0a8\uc720\uc815/3\uc8fc\ucc28"
Open

[3주차] 남유정/[feat] 게시글 도메인 API 구현#100
N-yujeong wants to merge 3 commits intoLeets-Official:남유정/mainfrom
N-yujeong:남유정/3주차

Conversation

@N-yujeong
Copy link
Copy Markdown

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

  • 게시글 목록 조회 API (GET /api/posts)
  • 게시글 상세 조회 API (GET /api/posts/{postId})
  • 게시글 작성 API (POST /api/posts)
  • 게시글 수정 API (PATCH /api/posts/{postId})
  • 게시글 삭제 API (DELETE /api/posts/{postId})
  • 프로젝트 구조 구성 (Controller/Service 레이어 분리)
  • [ x] 헬스체크 API 구현 (GET /health)
  • 문자열 2개 반환 API 구현 (POST /string/repeat)
  • 권장 추가 구현 반영 (선택)

2. 핵심 변경 사항

파일 변경 내용
PostController 게시글 CRUD 5개 엔드포인트 추가
PostService 목록(페이지네이션)/상세/작성/수정/삭제 비즈니스 로직 구현
Post category, thumbnailImageUrl 필드 추가, create() / update() 팩토리·수정 메서드 추가
Category 카테고리 엔티티 및 CategoryRepository 신규 추가
ApiResponse 공통 응답 래퍼 (success, error, errors 포함)
GlobalExceptionHandler PostNotFoundException, ForbiddenException, @Valid 검증 오류, 타입 불일치 등 전역 처리
SwaggerConfig SpringDoc OpenAPI 설정 추가
DataInitializer 앱 시작 시 더미 유저 1명, 카테고리 3개 자동 생성
domain/string 패키지 이동 기존 루트 → domain/string 으로 이동 (도메인 패키지 구조 정리)

3. 실행 및 검증 결과

  • 실패 케이스는 대표적으로 몇개만 스크린샷으로 첨부
게시글 목록 조회 성공
스크린샷 2026-04-07 095253
게시글 상세 조회 성공
스크린샷 2026-04-07 095310
게시글 상세 조회 실패
image
게시글 작성 성공
스크린샷 2026-04-07 094722
게시글 작성 실패
image
image
image
게시글 수정 성공
스크린샷 2026-04-07 095341
게시글 수정 실패
image
게시글 삭제 성공
스크린샷 2026-04-07 095401
게시글 삭제 실패
image
image

4. 완료 사항

  1. 게시글 CRUD API 5종 구현 (목록/상세/작성/수정/삭제)
  2. 공통 응답 포맷(ApiResponse) 및 전역 예외 처리(GlobalExceptionHandler) 추가
  3. Swagger(SpringDoc OpenAPI) 연동 및 API 문서화
  4. 카테고리 엔티티 추가 및 DataInitializer로 초기 데이터 자동 세팅
  5. 도메인 패키지 구조 정리 (domain/string으로 이동)

5. 추가 사항

제출 체크리스트

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

Reviewer 참고

@N-yujeong N-yujeong requested a review from a team April 7, 2026 05:10
@N-yujeong N-yujeong self-assigned this Apr 7, 2026
Copy link
Copy Markdown

@gusanans218 gusanans218 left a comment

Choose a reason for hiding this comment

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

전체적으로 구조가 잘 잡혀 있고 DTO 분리와 예외 처리, Swagger 적용까지 깔끔하게 구현되어 있어서 보기 좋았습니다!!
코드 가독성과 완성도 모두 좋은 것 같습니다 👍

Copy link
Copy Markdown

@Hanharam Hanharam left a comment

Choose a reason for hiding this comment

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

👍 DTO 중첩으로 사용하신 점과 전체적인 흐름이 좋았습니다! 최상위 커스텀 예외를 하나 만들고 다른 예외들은 상속받으면서 핸들러에는 부모 예외 하나만 두는 것도 좋을 것 같습니다!

Copy link
Copy Markdown

@jihoonkim501 jihoonkim501 left a comment

Choose a reason for hiding this comment

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

유정님 고생많으셨습니다~! 제 리뷰 한번 확인 부탁드려요~~!

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

Choose a reason for hiding this comment

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

Swagger 문서관리해주셨네요~! 지금도 충분히 세세하게 잘 작성해주셨는데 Docs 파일로 따로 관리해서 ( PostControllerDocs, PostController )
controller 코드는 설명을 제외하고 기능적인 코드만 남겨서 가독성을 높일 수 있는 방법도 있습니다. 수정은 아니고 참고만 해주시면 감사하겠습니다~!

Comment on lines +38 to +47
public PostDetailResponse getPost(Long postId) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new PostNotFoundException(postId));
return PostDetailResponse.from(post);
}

@Transactional
public Long createPost(PostCreateRequest request, Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다."));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

커스텀 예외처리와 표준(내장) 런타임 예외가 공존합니다! 커스텀 예외처리로 통일하는것을 추천드립니다! 추후 API 연동시에 프론트분들이 (아시겠지만) 어려워할수 있습니다..!


@Transactional
public void deletePost(Long postId, Long userId) {
Post post = postRepository.findById(postId)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

검증하는 부분이 반복되어서 따로 함수를 빼서 이용하면 SRP을 지키며 코드 가독성도 좋아진답니다!

Comment on lines +11 to +19
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(new Info()
.title("Leets-7th BE Blog API")
.description("[남유정] 미션 API 명세서")
.version("3주차"));
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

스웨거 꾸미기 좋습니다~! 👍

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