포시코딩

Controller와 Service의 역할 분리에 대해 본문

Node.js

Controller와 Service의 역할 분리에 대해

포시 2023. 1. 22. 17:16
728x90

개요

Layered Architecture Pattern으로 프로젝트를 구성하는데에 익숙해질 때 즈음

같이 공부하는 분들과 같이 다음의 주제에 대해 토론하는 시간이 있었다.

 

request로 전달받은 값에 대한 검증이나 

어떤 사용자인지에 따라 point 등의 추가 변수를 생성하여 처리하는 건

controller에서 해야할까 service에서 해야할까?

 

나는 controller파였다.

 

문제 발생

class UsersController {
  usersService = new UsersService();

  createUser = async (req, res) => {
    let { email, password, name, phone, address, admin } = req.body;
    admin = admin || false;

    // 손님일 경우 point: 1000000 설정
    // admin: false일 경우(전달값 없을 경우) 손님, admin: true일 경우 사장님
    const point = admin ? 0 : 1000000;
    
    // ...생략

 

발단은 내가 했던 이전 팀프로젝트를 리뷰하던중에 위의 코드에 대해 

왜 이렇게 했냐는 의문이 제기되서였다.

 

service에서 써야될 코드를 왜 controller에서 쓰고 있냐는 문제였는데

위에서 말했다시피 이런 input value에 대한 유효성 검증이나 가공 등의 처리는 모두

service에 넘어가기전에 controller에서 모두 진행하며 걸려야 된다고 생각했기 때문에 이렇게 작성했었다.

(point도 지금 상황에서 전달만 안됐을 뿐이지 input value가 될 수 있다고 생각함)

 

하지만 다른 사람들의 의견은 달랐다.

controller는 요청을 받아 service를 통해 처리하고 결과를 다시 응답으로 보내는 역할이라

위 코드 같은건 모두 service에 보내야 하는게 맞다고 주장했다.

 

나는 위 코드의 point 처리는 service에서 하는게 맞았다고 수긍과 함께

어느정도 반박에 동의하면서도

input value에 대한 처리는 controller에서 하는게 맞다는 의견을 굽히지 않았다.

 

좀처럼 결론이 나지 않아 제일 경험이 많은 튜터님께 물어봐 결론을 내리기로 했다.

 

결론

결론부터 말하자면 service에서 하는게 맞았다.

애초에 controller에서 하는건

SOLID 원칙의 S에 해당하는 '단일 책임의 원칙'을 위배한다는게 그 이유였다.

 

다만, request로 받은 값들에 대해 

진짜 service에 넘어가도 되는 값인지에 대한 체크는 controller에서 하는게 맞다고 하셨다.

 

그렇게 진행함으로서 service는 controller에서 받은 값들을 신뢰하게 되고

controller는 service에 값들을 전달하기 전에 해당 값들이

넘어가서 문제가 되지 않도록 체크하는 역할을 가져야한다고 볼 수 있겠다. 

즉, 쉽게말해 controller는 트롤 방지! (여기서 바로 이해됨)

 

솔직하게 말하면 위와 같은 코드를 작성하면서 나부터도 확신은 없었다.

그냥 예전부터 이렇게 해왔고 문제가 안되서 그렇게 생각했을뿐이었지..

 

정작 SOLID에 대해 공부했을 때

'아하 단일 책임의 원칙은 클래스당 하나의 역할을 부여하는 거구나' 라고만 이해했지 

이렇게 controller와 service간의 관계에 대해서는 생각해보지 못했던 것 같다.

 

오늘 이렇게 정리한 내용 덕분에 앞으로 controller와 service를 만들 때 

한층 더 명확환 역할 부여를 통해

지금까지보다 좀더 완벽한 Layered Architecture Pattern 프로젝트를 만들 수 있을 것 같다.

728x90