-
Notifications
You must be signed in to change notification settings - Fork 1
백엔드 컨벤션
나경호(Na Gyeongho) edited this page May 27, 2025
·
1 revision
Java 17 + Spring Boot 3.4.2
MySQL
Swagger UI
- 규칙
- 요청/응답 데이터는
@Schema
로 정의 - 컨트롤러단은 공통 클래스로 처리
- 요청/응답 데이터는
Notion 칸반보드
- [캠퍼스 핵데이 Java 코딩 컨벤션](https://naver.github.io/hackday-conventions-java/)를 따른다. ([적용 방법 참고 사이트](https://bestinu.tistory.com/64))
- 검증 메서드는 긍정문을 사용한다.
-
getter
가 아닌 메서드에서get-
을 사용하지 않는다. -
dto
라는 네이밍은 너무 포괄적이므로, 아래와 같이 목적을 정확하게 하자.- request, response, clientRequest, clientResponse
- 네이밍 형식
- API 엔드포인트 → kebab-case
- 클래스명 → PaskalCase
- DB 컬럼명 → snake_case
- 메서드/변수명, 요청/응답 필드명 → camelCase
- 패키지 구조는 도메인 기준으로 한다.
- 도메인 기준: 집중하기 편하다, 관심사가 확실하다
- 레이어 기준: 접근제어자를 타이트하게 잡을 수 있다. 어떤 레이어인지 확실하게 구분할 수 있다.
- https://github.com/depromeet/10mm-server/tree/develop/src/main/java/com/depromeet
- 클래스와 선언부 필드 사이는 개행한다.
-
@Valid
를 통한 입력값 검증을 진행한다. - Enum의 값을 정의할 때, 후행 쉼표를 사용한다.
- Lombok 라이브러리를 사용하되, 그 범위를 제한한다.
-
@Getter
,@NoArgsConstructor
,@RequiredArgsConstructor
- 어노테이션이 여럿 있는 경우, 중요한 것을 가장 상단에 배치한다.
- Lombok의 어노테이션을 가장 아래에 배치한다.
- 메서드의 순서는
public
을 위에 두되,private
의 경우 사용하는 메서드 아래에 둔다. - 필드 변수는
static final
→final
→instance variable
순서로 정의한다. (상수와 변수 사이 공백) - 웬만한 상황에서의 static factory method는 지양한다.
- 메서드 파라미터에는
final
을 사용하지 않는다.
-
@RestController
에서@RequestMapping
을 최상단에 사용하지 않는다.
-
@Transactional
어노테이션을 클래스 최상단에 작성하지 않는다.- 메서드 레벨에 필요한 경우 작성
-
@Table
과@Column
으로 테이블명, 컬럼명을 명시한다. - 예약어인 경우 복수형 또는 동의어를 찾아 작성한다 (예:
order
→orders
) -
@Column
어노테이션의nullable
여부를 명시한다. -
@Embeddable
내부에는@Embedded
을 사용하지 않는다.
- 메서드명은 한글로 작성한다.
@DisplayName
는 사용하지 않는다. - 데이터는 메서드 내부에서 설정한다.
- O: given절이 길어지지 않음
- X: Entity 검증을 거치지 않음, 문맥이 드러남
- 테스트 메서드에 given, when, then을 주석으로 표기한다.
- 두가지 이상이 될 경우 컴마(,)로 연결한다.
- 테스트 범위
- 비즈니스 로직 단위 (도메인 위주, 리소스 투자는 추후 결정)
- 로그 레벨은 아래와 같이 관리한다. 추가로 필요하다면 자유롭게 로깅한다.
- info: 외부 API 응답 / 요청은 남긴다.
- < 이 아래는 슬랙 봇 메시지로 알림 받아야 함 >
- warn: 내일 아침에 데일리에서 확인해도 무방한 사항
- error: 자다가도 일어나서 확인해야 하는 사항 → 외부 API 타임아웃, DB 저장 실패 등
-
커스텀 예외를 사용한다. 각각 추상화된 카테고리를 Advice에서 핸들링한다.
-
추상 예외 (
BadRequestException
등)을 각각의 도메인/서비스 레이어에서 구현한다. -
모든 Custom의 superclass로 잡으면 Advice에서 상태 코드를 알지 못한다. 즉 하위 레이어에서 응답 상태와 관련한 내용을 알게 된다.
-
Global 의존은 피해야하지만, Exception에 대해서는 어쩔 수 없이 글로벌 패키지를 받아오기로 한다. 추상화 예외의 변경 가능성이 적기 때문이다.
-
에러 메시지는 각각의 예외에 작성한다.
-
추후 디벨롭 예정
val error: String, val status: Int, val message: String, val timestamp: String
- 노션 칸반보드로 대체
<!---
❗️ 이슈 제목은 아래의 형식을 맞춰주세요
- `[Feat]` : 기능 추가 구현
- `[Fix]` : 코드 수정, 버그/오류 해결
- `[Performance]` : 개선할 성능 이슈
- `[Docs]` : README 등의 문서 수정
- `[Deploy]` : 배포 관련
- `[Refactor]` : 코드 리팩토링(기능 변경 없이 코드만 수정할 때)
- `[Test]`: 테스트 추가/수정
- `[Hotfix]` : 급한 핫픽스
-->
## ✨ 이슈 내용
-
## ✅ 체크리스트
- [ ] Assignees / Labels 선택
- [ ]
- [ ]
- PR 템플릿으로 생성 + Assignees 설정
- 머지 시 squash and merge → delete branch (깔끔한 브랜치 관리를 위해)
[Feat] 구현할 내용
<!-- -
❗️ PR 제목은 아래의 형식을 맞춰주세요
- `[Feat]` : 기능 추가 구현
- `[Fix]` : 코드 수정, 버그/오류 해결
- `[Performance]` : 개선할 성능 이슈
- `[Docs]` : README 등의 문서 수정
- `[Deploy]` : 배포 관련
- `[Refactor]` : 코드 리팩토링(기능 변경 없이 코드만 수정할 때)
- `[Test]`: 테스트 추가/수정
-->
### 관련 이슈가 있다면 적어주세요.
## 📌 개발 이유
## 💻 수정 사항
## 🧪 테스트 방법
## ⛳️ 고민한 점 || 궁굼한 점
## 🎯 리뷰 포인트
## 🙏 리뷰어에게 남기고 싶은 말
<!-- Reviewers, Assignees, Labels 지정해주세요 -->
## 📁 레퍼런스
Git Flow 전략
main
: QA 마친 최종 운영 서버
develop
: 개발하면서 코드 모을 공간 default
feature
: 기능을 개발하며 각자가 사용할 브랜치
- 브랜치명은 feat/이슈번호 형식
-
예시:
feat/1-initial-setup
-
예시:
develop → main PR 시 체크 사항
- develop 브랜치에서 main 브랜치 pull (conflict 있을 시, 해결)
- PR 머지 할 땐, squash 머지 대신 일반 commit merge (커밋 내역 유지 목적)
- 작업 브랜치에서 develop PR merge 시에는 squash 머지
-
feat
: 새로운 기능 구현 -
fix
: 코드 수정, 버그/오류 해결 -
chore
: 동작에 영향 없는 코드 or 변경 없는 변경 사항(주석 추가 등) -
docs
: README 등의 문서 수정 -
deploy
: 배포 관련 -
refac
: 전면 수정, 코드 리팩토링 -
test
: 테스트 추가/수정
feat : 내용
ex) git commit -m "fix : ProjectDetailResponseDto 수정"
ex) git commit -m "feat : 특정 프로젝트 가져오는 API"
- 하단에 기록 남기기!!! ⇒ 모두에게 도움이 되는 기록들
- 궁금한거나 필요한 부분은 그때그때 전부 편하게 얘기하기 ✨
- 최대한 빠르게 확인하고, 힘들다면 언제쯤 확인 가능할지 언급하기
- 찬기: 18:00 ~ 02:00 (많이 유동적)
- 경호: 19:00 ~ 01:00 (회사 10:00~19:00)
- 채영: 15:00 ~ 03:00 (많이 유동적)
- 슬랙 파트채널
- 편하게 작업 관련 부분 논의 및 소통
- 슬랙 팀채널
- 전체 공유가 필요하거나 작업 일정 등 정리된 내용 공유 시
- 깃허브 PR
- 최대한 자세히, 친절하게
- 최소 한명 이상 확인 하되, 기본적으로 모두가 approve 하는 방향으로 (너무 급할 때 제외)
- 노션 칸반
- 탬플릿 생성 시 상세하게 내용 작성
-
POST (Create):
add
(예:addUser
,addProduct
) -
GET (Read):
get
(예:getUser
,getProduct
) -
PUT (Update):
fix
(예:fixUser
,fixProduct
) -
DELETE (Delete):
remove
(예:removeUser
,removeProduct
)
-
Create:
create
(예:createUser
,createProduct
) -
Read:
find
(예:findUser
,findProduct
) -
Update:
update
(예:updateUser
,updateProduct
) -
Delete:
delete
(예:deleteUser
,deleteProduct
)
- 백엔드 컨벤션
- TestContainer 적용 이유
- DB Read replica 구성 (AWS RDS)
- RDS 프라이빗 설정 후 로컬 터널링
- 공통 성공/에러 응답 정의
- 테스트 환경 통합 작업
- 소셜 로그인 설계(Spring Security 없이 OAuth2.0)
- 클라우드 환경변수 관리 AWS SSM Parameter Store
- 코드단 제안 사항 (카카오톡 내용 요약)
- Spring에서 JWT 인증/인가 위치 제안(Filter와 Interceptor)
- 알림 아키텍처 정리
- 외부 API Call 및 무거운 작업 Serverless Lambda 로 분리
- Redis GEO (유저 위치 저장 및 검색)
- 푸시알림 권한 받는 시점
- TestConfig 및 (이전) Fixture 활용 방법
- 테스트 코드 개선 제안: Mock과 Fixture 패턴
- 테스트 객체 자동 생성
- 푸시알림 설계
- Fixture 및 Factory 활용 방법
- 로그 모니터링 시스템 구축
- 성능테스트 케이스