-
Notifications
You must be signed in to change notification settings - Fork 24
[김민준] sprint7 #209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 김민준
Are you sure you want to change the base?
The head ref may contain hidden characters: "\uAE40\uBBFC\uC900sprint7"
[김민준] sprint7 #209
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
바쁘신 수업 와중에 미션하느라 고생하셨습니다!
나중에 시간이 되시면 꼭 미션 미구현 부분 진행하여 보시길 바랍니다!
|
||
dependencies { | ||
implementation 'org.springframework.boot:spring-boot-starter-web' | ||
implementation 'de.codecentric:spring-boot-admin-starter-server:3.2.5' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3.2.5 버전은, 존재 안하는 버전입니다!
아래 링크 참조하여 주세요!
https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-server
annotationProcessor 'org.projectlombok:lombok' | ||
testImplementation 'org.springframework.boot:spring-boot-starter-test' | ||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' | ||
implementation 'org.springframework.boot:spring-boot-starter-validation' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
빌드가 안됩니다 ㅠㅠ,,
아래 기존 의존성들이 필요합니다!
수정되기 전 구성에서 'org.springframework.boot:spring-boot-starter-validation' 만 추가하시는게 더 안정적인 설정으로 보입니다!
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.4'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
Channel channel = channelRepository.findById(channelId) | ||
.orElseThrow(() -> new NoSuchElementException("Channel with id " + channelId + " not found")); | ||
if (!channelRepository.existsById(channelId)) { | ||
throw new NoSuchElementException("Channel with id " + channelId + " not found"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
커스텀 예외 사용 누락(여기 외에도 여러곳에서), 나중에 시간 되시면 GlobalExceptionHandler가 일관된 ErrorResponse를 만들어주게 커스텀 예외 사용 추천드립니다.
.body("[서버 내부 오류] 알 수 없는 에러가 발생했습니다."); | ||
} | ||
@ExceptionHandler(DiscodeitException.class) | ||
public ResponseEntity<ErrorResponse> handleDiscodeitException(DiscodeitException e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 모든 DiscodeitException을 HttpStatus.BAD_REQUEST로 고정하여 응답하고 있습니다.
하지만 ErrorCode에는 NOT_FOUND, FORBIDDEN 등 다양한 상태 코드가 정의되어 있습니다.
또한, ErrorResponse DTO를 새로 만드셨지만, 핸들러의 응답 본문(body)은 다른 ErrorResponse 객체(org.springframework.web.ErrorResponse)를 사용하고 있습니다.
import com.sprint.mission.discodeit.dto.ErrorResponse; // 직접 만든 DTO를 import 해야 합니다.
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice // @ControllerAdvice + @ResponseBody, API 응답에 적합합니다.
public class GlobalExceptionHandler {
@ExceptionHandler(DiscodeitException.class)
public ResponseEntity<ErrorResponse> handleDiscodeitException(DiscodeitException e) {
ErrorCode errorCode = e.getErrorCode();
ErrorResponse errorResponse = new ErrorResponse(
errorCode.getCode(),
errorCode.getMessage(),
e.getDetails(),
e.getClass().getSimpleName(),
errorCode.getStatus().value(),
e.getTimestamp()
);
return ResponseEntity
.status(errorCode.getStatus()) // ErrorCode에 정의된 HttpStatus
.body(errorResponse);
}
@Autowired | ||
private MessageRepository messageRepository; | ||
@Autowired | ||
private ReadStatusRepository readStatusRepository; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 아키텍처 레이어를 크게 4가지로 나누어서 보면 Controller, Service, Repository, Mapper 입니다.
레이어를 나누는 이유는 뭘까요?
Mapper, Service 각각에 역할 내지 책임은 무엇일까요 ?
Mapper에서 Repository 를 주입받아서 사용하는 상황에서 Service 레이어와의 차이점은 무엇일까요 ?
MapStruct나 일반적인 Mapper의 주된 책임은 객체의 데이터를 다른 형태의 객체로 "변환"하는 것입니다.
Optional.ofNullable(user.getProfileId()) | ||
.ifPresent(binaryContentRepository::deleteById); | ||
userStatusRepository.deleteByUserId(userId); | ||
if (userRepository.existsById(userId)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete 메서드에서 사용자가 존재할 때 (existsById가 true일 때) 예외를 던지고 있습니다.
!(NOT) 연산자를 활용하시면 됩니다.
@Transactional
@Override
public void delete(UUID userId) {
if (!userRepository.existsById(userId)) { // 사용자가 존재하지 않으면
throw new UserNotFoundException(userId);
}
userRepository.deleteById(userId);
}
요구사항
기본 요구사항
프로파일 기반 설정 관리
로그 관리
Lombok의 @slf4j 어노테이션을 활용해 로깅을 쉽게 추가할 수 있도록 구성하세요.
application.yaml에 기본 로깅 레벨을 설정하세요.
기본적으로 info 레벨로 설정합니다.
환경 별 적절한 로깅 레벨을 프로파일 별로 설정해보세요.
SQL 로그를 보기위해 설정했던 레벨은 유지합니다.
우리가 작성한 프로젝트의 로그는 개발 환경에서 debug, 운영 환경에서는 info 레벨로 설정합니다.
Spring Boot의 기본 로깅 구현체인 Logback의 설정 파일을 구성하세요.
로그 출력 예시
콘솔과 파일에 동시에 로그를 기록하도록 설정하세요.
프로젝트 루트
/.logs 경로에 저장되도록 설정하세요.로그 파일은 일자별로 롤링되도록 구성하세요.
로그 파일은 30일간 보관하도록 구성하세요.
서비스 레이어와 컨트롤러 레이어의 주요 메소드에 로깅을 추가하세요.
ERROR
,WARN
,INFO
,DEBUG
예외 처리 고도화
커스텀 예외를 설계하고 구현하세요.
com.sprint.mission.discodeit.exception[.{도메인}]
ErrorCode
Enum 클래스를 통해 예외 코드명과 메시지를 정의하세요.모든 예외의 기본이 되는
DiscodeitException
클래스를 정의하세요.DiscodeitException을 상속하는 주요 도메인 별 메인 예외 클래스를 정의하세요.
도메인 메인 예외 클래스를 상속하는 구체적인 예외 클래스를 정의하세요.
기존에 구현했던 예외를 커스텀 예외로 대체하세요.
ErrorResponse를 통해 일관된 예외 응답을 정의하세요.
앞서 정의한 ErrorResponse와 @RestControllerAdvice를 활용해 예외를 처리하는 예외 핸들러를 구현하세요.
멘토에게