NestJS graphql (3) 간단한 1:N 관계 예제

Peter·2020년 10월 14일
2

nestjs

목록 보기
6/11
post-thumbnail

0.목적

간단한 1:N 관계 예제를 통해, 1:N 관계에 대한 스키마,resolver를 어떻게 작성하는지 연습합니다.

1.스키마

post.graphql

type Post {
  id: Int!
  userId: Int!
  title: String!
  votes: Int
}

user.graphql

type Query {
    users: [User]
    getUserById(id: Int!): User
}

type User {
    id: Int!
    name: String!
    age: Int!
    posts: [Post]
}

사용자(User)는 여러개의 글(Post)를 게시할 수 있습니다.
이 경우 User:Post = 1:N 관계가 성립합니다.
그리고 위와 같이 User, Post, Query 스키마를 작성할 수 있습니다.

2.Resolver

user.resolver.ts

import { Args, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql';
import { User } from '../../autogen/schema.graphql';
import { UserService } from './user.service';
import { PostService } from '../post/post.service';

@Resolver('User')
export class UserResolver {
  constructor(private readonly userService: UserService, private readonly postService: PostService) {}

  @Query('users')
  async getAll(): Promise<User[]> {
    console.log(`getAll()`);
    return await this.userService.findAll();
  }

  @Query('getUserById')
  async getById(@Args('id') id: number) {
    console.log(`getById(id: ${id})`);
    return await this.userService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() user: User) {
    console.log(`posts(user: ${JSON.stringify(user)})`);
    const { id } = user;
    return await this.postService.findAllByUserId(id);
  }
}

post데이터는 user.id = post.userId 로 join 하여 가져올 수 있습니다.
user의 posts 필드는 위와 같이 @ResolveField()를 이용하여 postService를 통하여 데이터를 가져와서 fetch 하도록 설정할 수 있습니다.
그런데, user가 N명이면 postService.findAllByUserId()가 N번 호출되어 post db에서 데이터를 가져오는 행위를 N번 하는 비효율적인 일이 생길 수 있습니다.
이를 1:N 문제라고 하며, 이를 해결하는 방법으로 Dataloader를 많이 사용한다고 합니다.

0개의 댓글