nestjs with graphql - ch3 (ResolveField for array object)

Jae Min·2023년 12월 2일
0

nestjs with graphql

목록 보기
3/6
post-custom-banner

저번 글에서 @ResolveField() 를 통해서 추가 필드값을 받고, 해당 필드를 구현하기 위해서 @ResolveReference() 로 받아서 로직을 처리하는 방법을 구현했었다.

해당 내용을 공부해보니,
"이렇게 하면 N+1 문제가 발생해서 DataLoader 를 사용하면 문제를 해결할 수 있다~"
라는 글을 많이 봤는데, N+1 문제로 인해 쿼리 지연이 발생하려면, resolveField 가 배열, 즉 여러 값이 나와야 그러한 문제가 발생할 수 있겠다~ 라고 생각해서, 저번에는 필드가 배열이 아닌 하나의 값으로 구현을 했는데 이번에는 배열로 한번 받아보자 라는 생각에 배열로 구현을 해보기로 했다.

그런데, 아무리 해도 계속 배열로 뭔가 받질 못하는 것 같아서 수 많은 구글링과 phind 및 gpt 를 찾아봐도 내가 원하는 결과를 도출해낼 수 없었다.

구현하고자 하는 내용을 말하자면, 하나의 채팅방에 여러명의 유저가 있을 수 있고, 그러한 유저들의 정보를 채팅방 정보와 같이 조회를 하기 위한 기능이었다.

그래서 근본적으로 생각을 해봤는데,
1. 일단 ! 필드 자체는 배열이긴 하다.(하나의 채팅방에 유저는 여러명이니까) 그러면 이 resolveReference 가 쿼리를 여러번 수신해야 하는건가?
👉 이건 아무리 생각해도 말이 안된다. 그래프큐엘을 만든 팀에서 과연 그렇게 비효율적으로 만들었을까
2. 그렇다면 일단 resolveField 는 배열을 반환하는 것은 맞다.
3. 그리고 이거를 resolveReference 도 결국에는 한번만 받고, 그 배열을 풀어내기 위한 로직을 여러번 하는건가
4. 이거다 !

결국에 구현해냈다. 물론 디비를 연결해서 실제로 데이터 커넥션을 일으킨건 아니지만, 전체적인 흐름을 파악할 수 있게 되었다.

/// chat.resolver.ts
@ResolveField('users', () => [AccountModel])
  async getUsers(
    @Parent() chat: RoomModel,
  ): Promise<{ __typename: string; id: number }[]> {
    console.log(chat.roomId);
    const userIds: number[] = [1, 2, 3];
    return [
      { __typename: 'RoomModel', id: userIds[0] },
      { __typename: 'RoomModel', id: userIds[1] },
      { __typename: 'RoomModel', id: userIds[2] },
    ];
  }

특정 채팅방의 roomId 를 이용해서 디비에서 조회를 한 후, 해당 채팅방에 존재 하는 유저들의 id 가 1,2,3 이라고 하자.
이 유저들의 정보를 chat.resolver 에서 조회하는 것이 아닌, account.resolver 에서 조회하기 때문에, account.resolver 쪽으로 array object 을 보내준다.

@ResolveReference()
  resolveReference(reference: {
    __typename: string;
    id: string;
  }): AccountModel {
    return {
      id: reference.id,
      name: `${reference.id} + name`,
    };
  }

그러면 여기서 받아서 처리를 해주는데, 배열안에 아이템이 3개가 있기 때문에, @ResolveReference 를 3번 처리해줘야 한다.
이렇게 하나를 처리하기 위해 여러번의 쿼리를 실행할 경우 N+1 문제가 발생할 수 있다.


REF

https://unsplash.com/ko/%EC%82%AC%EC%A7%84/%ED%9A%8C%EC%83%89-%ED%83%9C%EC%96%91-%EC%A0%84%EC%A7%80%ED%8C%90-%EB%A1%9C%ED%8A%B8-dCx2xFuPWks

profile
자유로워지고 싶다면 기록하라.
post-custom-banner

0개의 댓글