[Node.js] 3. 서비스로 모듈 간 연결하기 (번역)

E-ρ(rho) 이로·2022년 6월 7일
0

✅ [번역] Tao of Node

목록 보기
3/3
post-thumbnail

Structure & Coding Practices

🗨 Use services to communicate between modules

MVC 구조를 갖는 어플리케이션에서는 앱 내의 기술적인 역할들(ex. service, schema...)을 기준으로 경계가 나누어졌었다. 즉, 로직이 다른 것에 대해서는 딱히 구분선이 명확하지 않은 것이다. 이전에도 언급했다시피, 나는 각 모듈이 도메인의 한 부분을 담당하는 형태의 모듈화된 구조를 굉장히 선호한다.

예를들어, (유저,품목,주문으로 이루어진 예시 어플리케이션에서) 인증 라우터와 계정 라우터를 위한 핸들러를 가지고있는 유저 모듈을 생각해보자. 또, 주문과 관련된 모든 것을 처리하는 주문 모듈도 가지고 있을 것 같다. 그런데 유저가 주문을 하는 동안 주소를 업데이트하는 그런 경우도 생길 수 있지 않겠는가?

이 로직은 언급한 두 모듈이 사용되는데, 우리는 이걸 정확히 어디서 처리를 해야하는가에 대한 난제에 직면하게 된다. 우리는 배달 모듈에 사용자의 상세 정보를 업데이트하는 데이터베이스 쿼리를 짤 수 있겠지만 이는 곧 우리가 유저와 관련된 로직을 유저모듈 밖에 두게 된다는 것을 의미하고, 만들어둔 경계를 흐트러트리는 셈이다.

이 사태를 피하기 위해서 유저와 관련된 로직들을 유저 모듈의 서비스에서 실행하는 것이 가장 좋다. 그 다음 배달(딜리버리) 모듈에서 함수를 부르면 된다. 경계를 유지하고 필요한 곳에 로직을 위치시키는 방법을 쓰자는 것이다. 배달(딜리버리) 모듈은 유저 정보가 업데이트 되었는지는 모르고, 단지 추상화(abstraction)에 의존한다.

// 👎 Don't break the boundaries of the domain modules
const placeOrderHandler = (req, res) => {
  const { products, updateShippingAddress } = req.body

  if (updateShippingAddress) {
    // Update the user's default shipping address
    const { user } = res.locals.user
    const { shippingAddress } = req.body
    knex('users').where('id' '=', user.id).update({ shippingAddress })
  }
}

// 👍 Communicate using services
const placeOrderHandler = (req, res) => {
  const { products, updateShippingAddress } = req.body

  if (updateShippingAddress) {
    // Update the user's default shipping address
    const { user } = res.locals.user
    const { shippingAddress } = req.body
    userService.updateShippingAddress(user.id, shippingAddress)
  }
}

만약 메인 application 밖으로 서비스를 추출해야한다면, 배달(딜리버리) 모듈은 그 어떤 변화도 없이 같은 기능을 호출해올 수 있다. 같은 방식으로, 유저 서비스에도 배달 모듈에 변화를 주지 않고도 같은 일을 할 수 있다.

0개의 댓글