Post

복잡한 서비스 로직 책임 분리하기

240828 TIL

복잡한 서비스 로직 책임 분리하기

♻️ 복잡한 서비스 로직 책임 분리하기

해당 PR 보러가기

문제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  async findAll(hashtag: string, queries: PostingQueryDto): Promise<PostingResponseDto[]> {
    const { type, orderBy, sortOrder, searchBy, search, pageCount, page } = queries;
    const queryBuilder = this.postingRepository.createQueryBuilder('posting');

    // 1건의 hashtag와 정확히 일치하는 값 검색
    queryBuilder
      .innerJoinAndSelect('posting.postingHashtags', 'postingHashtag')
      .innerJoinAndSelect('postingHashtag.hashtag', 'hashtag')
      .where('hashtag.name = :hashtag', { hashtag });

    // 게시물의 type 별로 조회, 미입력 시 모든 type
    if (type) {
      queryBuilder.andWhere('posting.type = :type', { type });
    }

    // search 입력된 경우 searchBy에 따라 검색
    if (search) {
      if (searchBy.split(',').length === 2) {
        queryBuilder.andWhere('posting.title LIKE :search OR posting.content LIKE :search', { search: `%${search}%` });
      } else {
        queryBuilder.andWhere(`posting.${searchBy} LIKE :search`, { search: `%${search}%` });
      }
    }

    // 입력된 값대로 정렬해 페이지네이션
    const postings = await queryBuilder
      .orderBy(`posting.${orderBy}`, sortOrder)
      .skip(page * pageCount)
      .take(pageCount)
      .getMany();

    // hashtag depth 정리 & content 글자 수 제한 적용해 반환
    return postings.map((posting) => {
      const arrangedPosting = this.getPostingObjWithHashtags(posting);
      arrangedPosting.content = arrangedPosting.content.substring(0, 20);

      return arrangedPosting;
    });
  }
  • 컨트롤러에서 호출하는 서비스 함수 하나에서 모든 작업을 하고 있다.
  • 가독성 개선과, 책임 분리를 목적으로 함수로 나누기로 했다.

시도 ✅

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  async findAll(hashtag: string, queries: PostingQueryDto): Promise<PostingResponseDto[]> {
    const rawPostings = await this.getRawPostings(hashtag, queries);

    // hashtag depth 정리 & content 글자 수 제한 적용해 반환
    return rawPostings.map((rawPosting) => {
      const posting = this.getPostingObjWithHashtags(rawPosting);
      posting.content = posting.content.substring(0, 20);

      return posting;
    });
  }

  // 입력된 쿼리 파라미터를 바탕으로 DB 쿼리를 빌드해 게시물 목록을 가져옵니다.
  private async getRawPostings(hashtag: string, queries: PostingQueryDto): Promise<Posting[]> {
    const { type, orderBy, sortOrder, searchBy, search, pageCount, page } = queries;

    const queryBuilder = this.postingRepository.createQueryBuilder('posting');

    ...

    // 입력된 값대로 정렬해 페이지네이션
    const rawPostings = await queryBuilder
      .orderBy(`posting.${orderBy}`, sortOrder)
      .skip(page * pageCount)
      .take(pageCount)
      .getMany();

    return rawPostings;
  }
  • 간단히 쿼리 빌더 부분만 따로 빼 함수를 만들었다.
This post is licensed under CC BY 4.0 by the author.