Layered Architecture Pattern - Service

윤태규·2024년 1월 17일

01. 서비스 (Service)

  • 1) 서비스 계층(Service Layer) 이란? 💡 **서비스 계층(Service Layer),** 다른 이름으로는 **비즈니스 로직 계층(Business logic layer)**은 아키텍처의 가장 **핵심적인 비즈니스 로직을 수행**하고 **클라이언트**가 원하는 **요구사항을 구현**하는 계층입니다. - **프레젠테이션 계층(Presentation Layer)**과 **데이터 엑세스 계층(Data Access Layer)** 사이에서 중간 **다리 역할**을 하며, 서로 다른 두 계층이 **직접 통신**하지 **않게 만들어 줍니다.** - **서비스(Service)**는 **데이터**가 필요할 때 **저장소(Repository)**에게 **데이터**를 요청합니다. - 어플리케이션의 **규모**가 커질수록, 서비스 계층의 **역할**과 **코드**의 복잡성도 점점 더 **커지게 됩니다.** - 어플리케이션의 **핵심적인 비즈니스 로직을 수행**하여 클라이언트들의 **요구사항을 반영**하여 원하는 결과를 **반환**해주는 계층입니다.
  • 2) 서비스 계층의 장단점 서비스 계층의 장점
    • 사용자의 유즈 케이스(Use Case)워크플로우(Workflow)를 명확히 정의하고 이해할 수 있도록 도와줍니다.

    • 비즈니스 로직이 API 뒤에 숨겨져 있으므로, 서비스 계층의 코드를 자유롭게 수정하거나 리팩터링할 수 있습니다.

    • 저장소 패턴(Repository Pattern)가짜 저장소(Fake Repository)와 조합하면 높은 수준테스트작성할 수 있습니다.

      서비스 계층의 단점

    • 서비스 계층 또한 다른 추상화 계층이므로, 잘못 사용하면 코드의 복잡성을 증가시킬 수 있습니다.

    • 서비스 계층이 다른 서비스 계층의존하는 경우, 의존성 관리가 복잡해질 수 있습니다.

    • 서비스 계층에 너무 많은 기능을 넣으면 빈약한 도메인 모델(Anemic Domain Model)과 같은 안티 패턴이 생길 수 있습니다.

  • 3) Express로 구현하는 서비스 계층
    Service

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/326eac47-e0a1-4871-a29b-4e7d80704a84/Untitled.png

  • 사용자의 요구사항을 처리하는 실세 중에 실세!!

    • 현업에서는 서비스 코드가 계속 확장되는 문제가 발생할 수 있습니다.
  • DB 정보가 필요할 때는 Repository에게 요청합니다.

  • 3계층 아키텍처 - posts.service.js

    // src/services/posts.service.js
    
    import { PostsRepository } from '../repositories/posts.repository.js';
    
    export class PostsService {
      postsRepository = new PostsRepository();
    
      findAllPosts = async () => {
        // 저장소(Repository)에게 데이터를 요청합니다.
        const posts = await this.postsRepository.findAllPosts();
    
        // 호출한 Post들을 가장 최신 게시글 부터 정렬합니다.
        posts.sort((a, b) => {
          return b.createdAt - a.createdAt;
        });
    
        // 비즈니스 로직을 수행한 후 사용자에게 보여줄 데이터를 가공합니다.
        return posts.map((post) => {
          return {
            postId: post.postId,
            nickname: post.nickname,
            title: post.title,
            createdAt: post.createdAt,
            updatedAt: post.updatedAt,
          };
        });
      };
    
      createPost = async (nickname, password, title, content) => {
        // 저장소(Repository)에게 데이터를 요청합니다.
        const createdPost = await this.postsRepository.createPost(
          nickname,
          password,
          title,
          content,
        );
    
        // 비즈니스 로직을 수행한 후 사용자에게 보여줄 데이터를 가공합니다.
        return {
          postId: createdPost.postId,
          nickname: createdPost.nickname,
          title: createdPost.title,
          content: createdPost.content,
          createdAt: createdPost.createdAt,
          updatedAt: createdPost.updatedAt,
        };
      };
    }

이번 서비스 계층(Service Layer)에서 PostsService 클래스가 PostsRepositoryfindAllPosts, createPost 메서드를 호출하는 것을 확인할 수 있는데요, 해당 코드는 서비스비즈니스 로직을 수행하는 데 필요한 데이터저장소 계층(Repository Layer)에게 요청하여 가져오는 것을 확인 할 수 있습니다.

또한, 서비스 계층에서는 return posts.map(post => {}); 와 같이 데이터를 가공하는 작업이 이루어집니다. 만약, 저장소 계층에서 받은 데이터를 그대로 클라이언트에게 전달한다면, 사용자의 비밀번호와 같은 민감한 정보까지 노출되는 보안 문제가 발생하여, 서버의 보안성이 떨어지는 결과를 낳게된답니다.

profile
끝까지 가자

0개의 댓글