Mutations

Mutations

GraphQL์—์„œ ์„œ๋ฒ„ ์ธก ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด Mutaion์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค (๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฌ๊ธฐ). ๊ณต์‹์ ์ธ Apollo ๋ฌธ์„œ๋Š” upvotePost() Mutation ์˜ˆ์ œ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ์ด Mutation์€ ํฌ์ŠคํŠธ votes์†์„ฑ ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค. Nest์—์„œ ๋™๋“ฑํ•œ ๋Œ์—ฐ๋ณ€์ด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š”@Mutation()๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Schema first

์ด์ „ ์„น์…˜์—์„œ ์‚ฌ์šฉํ•œ AuthorResolver๋ฅผ ํ™•์žฅ ํ•ด ๋ณด์ž (resolvers ์ฐธ์กฐ).

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return await this.authorsService.findOneById(id);
  }

  @Mutation()
  async upvotePost(@Args('postId') postId: number) {
    return await this.postsService.upvoteById({ id: postId });
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() { id }) {
    return await this.postsService.findAll({ authorId: id });
  }
}

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด PostsService (ํฌ์ŠคํŠธ ์กฐํšŒ ๋ฐ ํˆฌํ‘œ) ์†์„ฑ์œผ๋กœ ์ด๋™๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ๋‹ค.

Type definitions

๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋Š” ๊ธฐ์กด ์œ ํ˜• ์ •์˜์— ๋ฎคํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

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

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}

upvotePost(postId: Int!): Post ๋ณ€์ด๊ฐ€ ๊ฐ€๋Šฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

Code first

์ด์ „ ์„น์…˜์—์„œ ์‚ฌ์šฉ ๋œ AuthorResolver์— ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ถ”๊ฐ€ํ•ด ๋ณด์ž (resolvers ์ฐธ์กฐ).

@Resolver(of => Author)
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query(returns => Author, { name: 'author' })
  async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
    return await this.authorsService.findOneById(id);
  }

  @Mutation(returns => Post)
  async upvotePost(@Args({ name: 'postId', type: () => Int }) postId: number) {
    return await this.postsService.upvoteById({ id: postId });
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return await this.postsService.findAll({ authorId: id });
  }
}

upvotePost()๋Š”postId (Int)๋ฅผ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„์„œ ์—…๋ฐ์ดํŠธ ๋œ Post ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. resolvers ์„น์…˜์—์„œ์™€ ๊ฐ™์€ ์ด์œ ๋กœ ์˜ˆ์ƒ๋˜๋Š” ์œ ํ˜•์„ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฎคํ…Œ์ด์…˜์ด ๊ฐœ์ฒด๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ž…๋ ฅ ์œ ํ˜•์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@InputType()
export class UpvotePostInput {
  @Field() postId: number;
}

info ํžŒํŠธ @InputType()๊ณผ @Field()๋Š” ๋ชจ๋‘ type-graphql ํŒจํ‚ค์ง€์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ฆฌ์กธ๋ฒ„ ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

@Mutation(returns => Post)
async upvotePost(
  @Args('upvotePostData') upvotePostData: UpvotePostInput,
) {}

Last updated

Was this helpful?