Skip to content

Comments

[#3]; feat: 게시글 작성 API 기능 추가#10

Open
hubluish wants to merge 14 commits intomainfrom
feat/#3-article-create-api
Open

[#3]; feat: 게시글 작성 API 기능 추가#10
hubluish wants to merge 14 commits intomainfrom
feat/#3-article-create-api

Conversation

@hubluish
Copy link
Owner

Closes #3

  • Article 도메인 (Entity, Repository, Service, Controller, DTO) 구현
  • 게시글 생성 시 title, content 유효성 검사 추가 (@notblank)
  • 유효성 검사 실패 시 GlobalExceptionHandler를 통해 에러 응답 처리
  • 인증된 사용자 정보(@AuthenticationPrincipal)를 활용하여 게시글 작성자 자동 연결

특이사항

  • 제미나이가 짜 준 코드를 읽으면서 대충 3계층이 이런 식으로 이루어지구나 하는 감을 아주 조금이나마 잡은 것 같습니다
  • 음 근데 3계층 아키텍쳐랑 MVC랑 비슷한 거라고 생각했는데 아니었군요

- Article 엔티티 정의
- ArticleRepository,  ArticlerequestDto, ArticleResponseDto 정의
- ArticleService 클래스 생성
- createArticle 메서드 구현
- ArticleRequest와 사용자 이메일을 받아 게시글 생성
- 이메일을 통해 User 엔티티 조회
- Article 엔티티 생성하고 저장
- ArticleResponseDto 반환
- ArticleController 클래스 생성
- POST 엔드포인트 구현
- ArticleRequest 받아 게시글 요청 처리
- @AuthenticationPrincipal 통해 로그인한 사용자 정보 획득
- ArticleService 호출해 게시글 생성 및 응답 반환
- title과 content 필드에 @notblank 어노테이션 추가하여 필수 입력 값 검증
- MethodArgumentNotValidException 발생 시, 유효성 검사 실패 메시지를 포함한 ApiErrorResponse 반환
- ArticleService 단위 테스트 추가 (Mockito 사용)
- ArticleController 통합 테스트 추가 (MockMvc, @WithMockUser 사용)
- 성공 및 유효성 검사 실패 케이스 검증
- lombok 의존성 수정
- GlobalExceptionHandler의 APIErrorResponse 생성 방식 수정
- AuthController에 HttpStatus 추가
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements the article creation API feature with full validation support. The implementation follows a three-layer architecture pattern (Controller → Service → Repository) with proper separation of concerns.

  • Adds complete Article domain implementation with validation
  • Integrates Spring Security's @AuthenticationPrincipal for automatic author assignment
  • Updates GlobalExceptionHandler to support validation error responses

Reviewed Changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Article.java Entity definition with ManyToOne relationship to User
ArticleRepository.java JPA repository interface for Article persistence
ArticleService.java Business logic for article creation with user lookup
ArticleController.java REST endpoint for creating articles with validation
ArticleRequestDto.java Request DTO with @notblank validation constraints
ArticleResponseDto.java Response DTO mapping Article entity to API response
GlobalExceptionHandler.java Updated to handle validation exceptions and removed previous exception handlers
ArticleServiceTest.java Unit tests for article service layer
ArticleControllerTest.java Integration tests for article creation endpoint
build.gradle Fixed Lombok dependency configuration
AuthController.java Added HttpStatus import

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 13 to 32
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiErrorResponse handleIllegalArgument(IllegalArgumentException e, HttpServletRequest req) {
return ApiErrorResponse.of("BAD_REQUEST", e.getMessage(), req.getRequestURI());
public ResponseEntity<ApiErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex, HttpServletRequest request) {
ApiErrorResponse errorResponse = ApiErrorResponse.of(
HttpStatus.BAD_REQUEST.toString(),
ex.getMessage(),
request.getRequestURI()
);
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiErrorResponse handleOthers(Exception e, HttpServletRequest req) {
return ApiErrorResponse.of("INTERNAL_SERVER_ERROR", "Unexpected error", req.getRequestURI());
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ApiErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
String errorMessage = ex.getBindingResult().getFieldError().getDefaultMessage();
ApiErrorResponse errorResponse = ApiErrorResponse.of(
HttpStatus.BAD_REQUEST.toString(),
errorMessage,
request.getRequestURI()
);
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

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

The removal of the DuplicateEmailException handler breaks existing functionality in AuthService, which still throws this exception. This will result in unhandled exceptions when duplicate email registration is attempted. Either restore the handler or add it back to maintain backward compatibility.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

뭐야 이것도 너무 중요한거네요 exceptionHandler가 작동하는 흐름을 이해해야합니다 자바의 예외계층도 한번 공부해보셔야하구요~

import com.example.backendmentoring.auth.dto.SignUpRequest;
import com.example.backendmentoring.auth.dto.SignUpResponse;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

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

This import appears to be unused in the file. The existing code likely uses @ResponseStatus annotation which is already imported. Remove this unused import.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

이건 잔소리느낌이긴한데 보통 임포트문을 보고 의존성을 파악하기때문에 안쓰는건 지우라는 의미입니다!

Copy link
Collaborator

@seulnan seulnan left a comment

Choose a reason for hiding this comment

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

고생하셨습니다. 코멘트 단건 꼭 공부해보세요.

++) 3계층과 MVC가 어떻게 다른지 느꼈다면 그 느낀점을 구체적으로 적어주시면 더 좋습니다.

- CreateArticleUseCase / CreateArticleService 도입
- 컨트롤러 수정
- 4계층에 따른 아티클 도메인 파일 생성
- UserReader, UserReaderImpl 추가
- ArticleServiceTest 수정
- null 여부 확인 가능
@hubluish hubluish requested a review from seulnan November 17, 2025 04:55
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.

feat: 게시글 작성 API 구현

2 participants