서버 기본설계

유정현·2023년 12월 14일

개요


서버의 주요 역할을 비즈니스 로직의 처리이다. 이런 비즈니스 로직을 처리하기 위해 백엔드 서버에서는 일반적으로 Controller, Service, Repository, Domain 등을 사용한다. 이름이 다르더라도 유사한 역할을 하는 것들을 사용한다. MyBatis를 사용한다면 Repository를 쓰지 않고 Mapper를 사용할 수 있는 것이 그것이다.

구성 상세


  1. Controller : 요청을 받아서 처리하는 곳이다. 컨트롤러는 보통 요청을 통해 필요한 정보나 객체를 받아서 서비스 레이어로 전달을 하고 결과를 받아서 응답값을 보내는 역할을 한다. 즉, 비즈니스 로직의 문과 같다.
  2. Service : 서비스는 비즈니스 로직을 처리하는 부분이다. 예를 들어 회원을 추가할 땐 컨틀롤러에서 새로운 유저의 정보를 전달 받고, 내부적으로 필요한 처리를 실행하는 곳이다.
    ex) 내부적으로 필요한 처리: 회원 가입을 하더라도 가입 후 이력을 저장할 수 있는데 그런 것들은 한 번에 처리할 수 있는 곳이다.
  3. Repository : DB와 연결이 돼있는 곳으로 DB와 서버 사이에서 직접적인 IO가 일어나는 곳이다.
  4. Domain : vo,dto,model 처럼 유저의 정보를 담거나 요구사항을 처리하기 위한 정보를 담는 그릇이다.

레파지토리와 서비스 레이어의 관계

스프링을 처음 배울 때 서비스의 메소드와 레파지토리의 메소드 명을 똑같게 사용했다. 예를 들어 유저의 상세를 조회한다면, 둘다 selectOne을 사용한다던가 유저 목록을 조회하면 selectList를 사용한다던가 했다.

기능은 비슷할 수 있어도 역할이 명확히 다르다. 그렇기 때문에 메소드 네이밍도 달라져야한다.

내 생각도 이게 맞다. ServiceLayer는 비즈니스 로직 처리를 하는 곳이니 Repository와 같을 수 없고, 기능이 똑같더라도 내부 처리 과정과 목적이 애초에 다르기 때문에 네이밍도 다르게 하는 것이 맞다.

나만 몰랐던 이야기일 수도 있지만.,. 그걸 적는 게 TIL이니까.. 부끄럽지만 당당하게 ..,

완전히 새롭게 익힌 내용들

Test케이스 작성

  1. @beforeEach : 테스트 클래스 내부 메소드 테스트 직전에 실행해주는 메소드에 추가해준다.
  2. @afterEach : 테스트 클래스 내부 메소드 테스트 직후에 실행해주는 메소드에 추가한다.
  3. given, when, then : 테스트를 세 단계로 끊어서 한다.

assertJ vs Junit

두 라이브러리는 import부터 매우 유사하다.

assertJ : org.assertj.core.api.Assertions
junit : org.junit.jupiter.api.Assertions

아래 코드는 내가 잠깐이지만 사용했던 메소드이다.

assertJ : assertThat(원본).isEqualsTo(예상결과)
junit : assertEquals(예상결과, 원본)
  1. 클린 코드는 메소드에 매개변수(파라미터)를 하나만 전달하는 코드다. 그래야 언제 써도 헷갈리지 않는다.
  2. 메소드명, 변수명은 길더라도 의도를 정확하게 내비춰야한다.

위 두 가지 클린코드의 나름 법칙(?) 같은 것을 기준으로 생각해보면 assertJ가 조금 더 나은 것 같다. 난 아직 써보지 않았지만 컬렉션을 다룰 때도 assertJ가 좀 더 많은 테스트 도구를 지원한다고 한다. 정확한 이야기는 나중에 따로 블로그에 정리해야 될 것 같다.

Null체크를 위한 Optional

Optional<Member>

이건 Member 사용자 정의 타입 변수를 다루기 위한 OptionalType이다. 이걸 이용하면 Null인지 아닌지 부터 filter,map 등 다양한 Optional메소드를 지원해준다. 이렇게 쓰면 try-catch를 쓴다거나 따로 null체크 하는 코드를 작성하지 않아도 되기 때문에 아주 반가운 친구다. 이 친구도 나중에 따로 블로그 글로 다뤄봐야겠다.

profile
코딩하는 감자입니다.

0개의 댓글