-
Notifications
You must be signed in to change notification settings - Fork 4
백엔드 컨벤션 및 전략
Minhwan Yu edited this page Aug 16, 2022
·
3 revisions
OOP, CleanCode를 지향하자
테스트도 프로덕트 코드처럼 생각하자.
Presentation - Application - Domain - Infrastructure
- 단위 테스트는 필수
- 테스트 템플릿
- given when then 주석붙이기
- Fixture 관리
- 비즈니스 로직 테스트는 통합 테스트를 이용해보자
@SpringBootTest
-
jacoco , sonarcloud
중에 선택 사용 (미정)- 도입하고 커버리지를 조금씩 올리자
- `@DisplayName("저장 성공")
- save_success()
save_success
save_duplicateName_fail
(유저 저장 성공)
(이름 중복으로 인한 실패)
- Enum errocode
- (A001 , HttpStatus.NotFound , “존재하지 않은 유저입니다” )
- 보내는 메시지의 경우 예외 안에 있는 메시지를 보내도록
- (A001 , HttpStatus.NotFound , “존재하지 않은 유저입니다” )
public class BusinessException extends RuntimeException {
private ErrorCode errorCode;
public BusinessException(String message, ErrorCode errorCode) {
super(message);
this.errorCode = errorCode;
}
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
public ErrorCode getErrorCode() {
return errorCode;
}
}
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum ErrorCode {
// Common
INVALID_INPUT_VALUE(HttpStatus., "C001", " Invalid Input Value"),
METHOD_NOT_ALLOWED(405, "C002", " Invalid Input Value"),
INTERNAL_SERVER_ERROR(500, "C004", "Server Error"),
INVALID_TYPE_VALUE(400, "C005", " Invalid Type Value"),
HANDLE_ACCESS_DENIED(403, "C006", "Access is Denied"),
// Member
EMAIL_DUPLICATION(400, "M001", "Email is Duplication"),
LOGIN_INPUT_INVALID(400, "M002", "Login input is invalid"),
// Coupon
COUPON_ALREADY_USE(400, "CO001", "Coupon was already used"),
COUPON_EXPIRE(400, "CO002", "Coupon was already expired")
private final String code;
private final String message;
private int status;
ErrorCode(final int status, final String code, final String message) {
this.status = status;
this.message = message;
this.code = code;
}
public String getMessage() {
return this.message;
}
public String getCode() {
return code;
}
public int getStatus() {
return status;
}
}
-
최상위 예외 : BusinessException
- 도메인 예외 : UserException
- 상세 예외 : UserDuplicateException , UserInvalidException
- 도메인 예외 : UserException
-
custom Exception 사용
- 유저를 예로
public class UserException extends BusinessException{
public UserException(String message, ErrorCode errorCode) {
super(message, errorCode);
}
}
public class UserCustomException extends UserException {
private static final ErrorCode errorCode = ErrorCode.USER_NOT_FOUND;
public UserCustomException(String message) {
super(message, errorCode);
}
}
- 라이브러리 사용하지 않고 DTO 자체 변환 메소드 구현해 사용
- Controller에서 받은 request, response DTO를 그대로 사용
- 변환 위치
- DTO에서 반환하도록
- from, toEntity
- DTO에서 반환하도록
- 후에 리팩토링 하는 식으로 진행
변경에 유연한 설계, 우리는 2가지 종류의 DTO를 쓴다!
- Rest API Best Practice로 따라가자
- 단수 지양
- 복수 지향
- 동사 지양
- 명사 지향
(번역) RESTful API Designing guidelines - The best practices
-
/api/
를 prefix로 붙여주자
- 커스텀 예외는 어떤 레벨로 찍을까?
-
error
→ Exception (예상하지 못한 에러는 error) -
warn
→ 커스텀 예외 (예상할 수 있는 에러는 warn)- 원래는
info
인듯하나 편의성을 위해warn
으로 설정
- 원래는
-
- SQL 로깅까지
- 비동기 로깅 → logback , log4j
-
cloudwatch 로그 연동
및 슬랙에 error시 알람 올 수 있도록
AWS CloudWatch Logs Dashboard 구성
Log4j2 및 Logback의 Async Logging 성능 테스트 비교
- 저희팀은 기본적으로 git flow를 따르되 release 브랜치의 경우 현재 상황에서는 필요없다고 판단하여 제외하고 main, develop, feature, hotfix 브랜치만 사용합니다.
- main - 최종 배포 브랜치입니다.
- develop - 배포 전 모든 기능 개발 및 수정 사항을 해당 브랜치로 Merge 합니다.
- feature - 기능 개발 브랜치입니다.
- hotfix - 최종 배포 버전에서 발생한 버그를 수정 하는 브랜치입니다.
- 브랜치간 merge 전략은 다음 규칙을 따릅니다.
- develop → main :
crate a merge commit
옵션 사용 ( 이때, 태그를 추가하게 됩니다. ) - feature → develop :
squash and merge
옵션 사용 - develop → feature :
rebase and merge
옵션 사용
- develop → main :
- Jira를 사용하기 때문에 이슈ID를 사용하여 작업합니다.
- 예) feat/WOOR-1
[WOOR-1] feat: 회원 로그인 api 구현
- feat : 새로운 기능 추가
- fix : 버그 수정
- style : 코드 포맷팅, 세미클론 누락, 코드 변경이 없는 경우
- refactor : 코드 리팩토링
- test : 테스트 코드, 리팩토링 테스트 코드 추가
- docs : 문서 수정
- chore : 빌드 업무 수정, 패키지 매니저 수정 및 그 외의 작업
[WOOR-1] feat: 회원 로그인 API 구현
- PR이 올라오면, 리뷰어를 할당하고 두명 이상의 approve가 있어야 merge할 수 있습니다.
- 리뷰어는
24
시간안에 리뷰를 수행해야합니다.
- 리뷰어는
- PR을 올린 담당자가 리뷰를 통해 수정을 마쳤을 때 merge 합니다.
- 도메인에서 하기에 복잡한 validation은 Validator 유틸성 클래스를 만들어서 진행