Conversation
- 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 추가
There was a problem hiding this comment.
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.
src/main/java/com/example/backendmentoring/common/GlobalExceptionHandler.java
Outdated
Show resolved
Hide resolved
| @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); | ||
| } |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
뭐야 이것도 너무 중요한거네요 exceptionHandler가 작동하는 흐름을 이해해야합니다 자바의 예외계층도 한번 공부해보셔야하구요~
| import com.example.backendmentoring.auth.dto.SignUpRequest; | ||
| import com.example.backendmentoring.auth.dto.SignUpResponse; | ||
| import jakarta.validation.Valid; | ||
| import org.springframework.http.HttpStatus; |
There was a problem hiding this comment.
This import appears to be unused in the file. The existing code likely uses @ResponseStatus annotation which is already imported. Remove this unused import.
There was a problem hiding this comment.
이건 잔소리느낌이긴한데 보통 임포트문을 보고 의존성을 파악하기때문에 안쓰는건 지우라는 의미입니다!
seulnan
left a comment
There was a problem hiding this comment.
고생하셨습니다. 코멘트 단건 꼭 공부해보세요.
++) 3계층과 MVC가 어떻게 다른지 느꼈다면 그 느낀점을 구체적으로 적어주시면 더 좋습니다.
- CreateArticleUseCase / CreateArticleService 도입 - 컨트롤러 수정 - 4계층에 따른 아티클 도메인 파일 생성
- UserReader, UserReaderImpl 추가 - ArticleServiceTest 수정
- null 여부 확인 가능
Closes #3
특이사항