[Spring] Controller, Service를 분리 작성해야 하는 이유

728x90
Q. Controller에서 전부 구현하면 안되나요? Service를 왜 만들어야하죠?

Controller에 다 구현해도 똑같이 동작하기 때문에 이에 대한 의문이 들기 쉽습니다. 생각보다 많은 초보 개발자 분들이 왜 이런 구조로 분리하는지 이유를 모르고 다들 분리하기 때문에 그냥 분리합니다. 여러 다른 이유로 소프트웨어 아키텍처를 변경해야 할때 유연하게 변경할 수 없습니다. 그러나 원리를 알면 다음에 더 좋은 아키텍처를 만드는데 비슷한 원리를 적용할 수 있습니다.


🟦 1) API의 추가 및 변경될 경우

RESTful API를 통해 서비스를 운영하고 있다고 가정합시다. 사이트 반응속도가 너무 느려 서비스를 Light House로 분석해보니 하나의 페이지에서 너무 많은 API를 호출해 문제가 생겼다고 합니다. 이러한 문제를 해결하기 위해 팀에서는 graphql을 도입하기로 결정하였다고 합시다.

이때 만약 Controller에 모든 기능을 구현하였다면, Grapqhql API를 구현하는 Controller에 또 다시 구현해야하지만 Service에 기능을 구현하였다면 이럴 문제가 없습니다.

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

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

🟦 2) 트랜잭션 처리

Spring에서 Service의 고유한 기능 중 하나는 Transaction 처리 기능입니다.

트랜잭션이란, DB 업데이트시 일련의 업데이트 과정을 한번에 처리하고 실패시 전체 롤백, 성공시 전체 실패를 해주는 기능입니다.

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

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

🟦 3) Controller와 Service의 역할

웹 서비스를 만들때 많이 사용하는 두가지 계층 구조입니다.

Spring Application Layered Pattern은 Spring에서 흔히 사용하는 계층 구조로 Web Layer에서 사용자의 요청을 받고 Service Layer에서 실제 요청을 처리하고, Repository Layer에서 통해 Data를 조회 변경합니다.

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

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

이는 단일 책임 원칙을 지키는 기본입니다.

[참고] https://velog.io/@couchcoding/Spring-Controller-Service는-왜-분리해야할까

728x90