Skip to content

백엔드 코드 컨벤션

hong-sile edited this page Aug 17, 2023 · 8 revisions

아키텍쳐

Layered Architecture

패키지 구조

도메인 별 패키지 구조

  • com.emmsale

    ControllerAdvice, Application 파일

    • base

      BaseEntity, BaseException 등

    • config

      config 파일

    • resolver

      argument resolver

    • career, member, … (도메인 별 패키지)

      • domain

        Domain 객체, 값 객체 등

      • api

        Controller

      • applicatoin

        Service

      • exception

        ExceptionType Enum 클래스

        Exception 도메인 별 예외 템플릿

코드 컨벤션

  • intellij java google style 확정

  • 불변 지역변수/멤버변수 등등에 final 붙인다.

    • 클래스에는 안 붙임
    • 설정에서 generate 단축키 사용 시 'final’ 키워드가 포함되도록 설정하기

    image

  • Service는 조회 API를 모아둔 QueryService와 수정 API를 모아둔 CommandService로 분리해서 작성한다.

    image

커스텀 에러

  • ExceptionType은 예외의 데이터(에러 코드, 에러 메시지)를 담고 있는 Enum 데이터

  • BaseException 인터페이스가 있고, 도메인 별로 Exception 구현체를 만든다.

  • ExceptionResponse DTO 클래스(에러 메시지를 포함함)는 Exception 구현체 클래스의 이너 클래스로 구현.

  • 우리끼리 약속

    • 에러메시지는 최대한 상세하게
    • 기본 제공 Exception보다 커스텀 에러를 사용하자.
    • 만드려는 Exception이 이미 존재하는지 확인하고 만들기

테스트 코드

  • API Test, ServiceTest는 미리 만들어둔 Helper 클래스를 상속한다.

    @WebMvcTest
    @ExtendWith({RestDocumentationExtension.class, SpringExtension.class})
    public class MockMvcTestHelper {
    
      @Autowired
      protected MockMvc mockMvc;
    
      @Autowired
      protected ObjectMapper objectMapper;
    
      @MockBean
      private MemberArgumentResolver memberArgumentResolver;
    
      @BeforeEach
      void setUp(final WebApplicationContext applicationContext,
          final RestDocumentationContextProvider provider) {
        mockMvc = MockMvcBuilders.webAppContextSetup(applicationContext)
            .apply(documentationConfiguration(provider).operationPreprocessors()
                .withRequestDefaults(prettyPrint())
                .withResponseDefaults(prettyPrint()))
            .build();
      }
    }
    @SpringBootTest
    @Sql(value = "/data-test.sql", executionPhase = ExecutionPhase.BEFORE_TEST_METHOD)
    public class ServiceIntegrationTestHelper {
    
    }

@Test 어노테이션과 @DisplayName 어노테이션은 다음과 같은 순서로 작성한다.

@Test
@DisplayName
  • Fixture 사용 여부 - 사용한다.

  • DisplayName 네이밍 규칙 - 한글

    • Given-When-Then 기반으로 아래 예시처럼
    • [에러] 쿠폰이 5장일 때 6장 발급 신청을 하게 되면 IllegalArgumentException이 발생할 수 있다.
    • [성공] 쿠폰이 5장일 때 5장 발급 신청을 할 수 있다.
  • 테스트 메서드 네이밍 규칙 - 영문

    • 본인 재량껏
  • 테스트 내부 구성은 자유

  • @nested 사용 여부는 편한대로

  • 코드 커버리지는 신경쓰지 않되 각자 재량에 따라 가능한한 유효성 검증을 구현한다.

  • restdocs를 위한 문서화 테스트에서 파라미터나, request, response들의 snippet들도 작성하여 문서화한다.