[Spring] Controller, Service는 왜 분리해야할까?

카우치코딩·2022년 11월 30일
49

Spring

목록 보기
3/3
post-thumbnail
post-custom-banner

Spring을 처음 배우는 모든 학생 분들이 가장 많이하는 질문
그냥 Controller에서 전부 구현하면 안되나요? Service를 왜 만들어야하죠? 라는 질문입니다.
Controller에 다 구현해도 똑같이 동작하기 떄문에 이런 질문을 가질 수 있습니다.
또한 생각보다 많은 초보 개발자 분들이 왜 이런 구조로 분리하는지 이유를 모르고 다들 분리하기 때문에 그냥 분리합니다. 여러 다른이유로 소프트웨어 아키텍처를 변경해야 할때 유연하게 변경할 수 없습니다. 그러나 원리를 알면 다음에 더 좋은 아키텍처를 만드는데 비슷한 원리를 적용할 수 있습니다.

이번 포스팅에서는 Controller, Service를 분리하는 이유들에 대해 알아보겠습니다.

API의 추가 및 변경될 경우

RESTful API를 통해 서비스를 운영하고 있다고 가정합시다. 사이트 반응속도가 너무 느려 서비스를 Light House로 분석해보니 하나의 페이지에서 너무 많은 API를 호출해 문제가 생겼다고 합니다. 이러한 문제를 해결하기 위해 팀에서는 graphql을 도입하기로 결정하였다고 합시다.
이때 만약 Controller에 모든 기능을 구현하였다면, Grapqhql API를 구현하는 Controller에 또 다시 구현해야하지만 Service에 기능을 구현하였다면 이럴 문제가 없습니다.

위 그림처럼 GqlController를 새로 만들어 Service에 연결해주면 됩니다.

이렇게 되면 또 하나의 장점은 점진적으로 API를 변경할 수 있다는 점입니다.
만약 API를 변경하기 위해 전부 컨트롤러를 변경한다면 모든 API가 변경된 이후에야 배포를 할 수 있습니다.
그러나 이런식으로 변경된 부분만 GqlController로 옮길 수 있으면 두가지 API를 동시에 사용할 수 있어 점진적으로 서비스를 개선하여 한번에 변경할때 생기는 문제들을 미리 예방 할 수 있습니다.

트랜잭션 처리

Spring에서 Service의 고유한 기능 중 하나는 Transaction 처리 기능입니다.
트랜잭션이란 DB 업데이트시 일련의 업데이트 과정을 한번에 처리하고 실패시 전체 롤백, 성공시 전체 실패를 해주는 기능입니다. 송금을 예제로 들면 다음과 같습니다.

트랜잭션이 없는 상태의 송금 실패 시나리오입니다. DB에서 B의 계좌를 업데이트 하는것을 실패하였습니다.
트랜잭션이 없다면 A의 계좌를 롤백하지 않아 A의 계좌에만 5000원이 감소하게됩니다.
그러나 트랜잭션을 사용한다면 5에서 실패하였을때 A의 계좌도 다시 롤백을 하기 때문에 실패에도 안전하게 돈을 보존할 수 있습니다.

Service에서는 클래스나 메서드에 @Transaction을 사용하여 Exception이 발생할 경우 모든 DB업데이트를 롤백하는 과정을 가질 수 있습니다.

Controller와 Service의 역할

Spring Application Layered Pattern

Domain Driven Design Layered Pattern

위의 두 그림은 웹 서비스를 만들때 많이 사용하는 두가지 계층 구조입니다.
Spring Application Layered Pattern은 Spring에서 흔히 사용하는 계층 구조로 Web Layer에서 사용자의 요청을 받고 Service Layer에서 실제 요청을 처리하고, Repository Layer에서 통해 Data를 조회 변경합니다.

Domain Driven Design Layered Pattern에서는 User Interface Layer에서 사용자의 요청을 받고 응답을 만들며 Application Layer에서는 기능을 제공합니다. Domain Layer에서는 기능을 제공하기 위한 실제 변경 작업을 진행하며 Infrastructure Layer에서는 Database, 다른 Application, 웹 프레임워크등 인프라에 접근하도록 인터페이스를 제공하는 레이어입니다.

Controller는 Web Layer와 User Interface Layer에 해당하고,
Service는 Service Layer와 Application Layer 혹은 Domain Layer에 해당합니다.

Controller에서는 사용자의 입력처리와 응답에만 집중하고, Service에서는 실제 기능을 어떤식으로 제공하는지에 대해서만 집중하여야 나중에 다른 팀원이 코드를 수정할 때도 어떤 기능이 어디에 있는지 쉽게 알 수 있고, 변경하기 유리합니다.
이는 단일 책임 원칙을 지키는 기본입니다.

About Couchcoding

카우치코딩에서는 1:1 코딩 문제해결 멘토링 서비스입니다. 가르치는데 관심있는 멘토분들이나 문제해결이 필요한 멘티분들 방문해주세요~
또한 별도로 6주 포트폴리오 수업을 진행중에있습니다. 혼자 포트폴리오 준비를 하는데 어려움이 있으면 관심가져주세요~

카우치코딩 고동휘 멘토의 글입니다.

profile
포트폴리오 수업 & 코딩 멘토링 서비스 카우치코딩입니다.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 12월 23일

@Transaction 애너테이션은 Service Layer의 고유한 기능이 아닙니다

답글 달기