본문 바로가기
nest.js

Nest.js에서 GraphQL 사용해 보기 (2024.05.30)

by goblin- 2024. 5. 30.

GraphQL 개요

  • GraphQL: 자동화된 기능이 많아 사용하기 쉽습니다.
  • Code-First vs Schema-First:
    • Schema-First: 기존 Apollo-server 방식으로, typeDefs를 직접 작성합니다.
    • Code-First: Nest.js 방식으로, API 코드를 먼저 작성하고 스키마는 자동으로 생성됩니다.

Nest.js GraphQL 설치

Nest.js 공식 문서에서 샘플 코드와 설치 방법을 참고할 있습니다. 아래는 GraphQL Nest.js 프로젝트에 설정하는 방법입니다.

 

 

프로젝트 구조

src
├── main.ts
├── app.module.ts
├── cats
│   ├── cats.module.ts
│   ├── cats.resolver.ts
│   └── cats.service.ts

 

 

예시 코드

main.ts

Nest 애플리케이션의 엔트리 포인트로, AppModule 불러와 애플리케이션을 시작합니다.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

// Nest 애플리케이션의 엔트리 포인트로, AppModule을 불러와 애플리케이션을 시작합니다.
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

 

 

app.module.ts

모든 모듈을 합쳐서 설정합니다.

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'schema.gql', // 스키마 파일을 자동으로 생성합니다.
    }),
    CatsModule, // Cats 모듈을 임포트합니다.
  ],
})
export class AppModule {}

 

 

cats/cats.module.ts

Cats 모듈을 정의합니다.

import { Module } from '@nestjs/common';
import { CatsResolver } from './cats.resolver';
import { CatsService } from './cats.service';

@Module({
  providers: [CatsResolver, CatsService], // 리졸버와 서비스를 주입
})
export class CatsModule {}

 

cats/cats.resolver.ts

GraphQL 리졸버를 정의합니다.

import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
import { CatsService } from './cats.service';
import { Cat } from './models/cat.model';
import { CreateCatInput } from './dto/create-cat.input';

@Resolver(() => Cat)
export class CatsResolver {
  constructor(private readonly catsService: CatsService) {} // CatsService를 의존성 주입 받습니다.

  @Query(() => [Cat], { name: 'cats' }) // 'cats' 쿼리를 정의합니다.
  findAll(): Cat[] {
    return this.catsService.findAll(); // 서비스의 findAll 메서드를 호출합니다.
  }

  @Mutation(() => Cat) // 'createCat' 뮤테이션을 정의합니다.
  createCat(@Args('createCatInput') createCatInput: CreateCatInput): Cat {
    return this.catsService.create(createCatInput); // 서비스의 create 메서드를 호출합니다.
  }
}

 

 

cats/cats.service.ts

비즈니스 로직을 처리하는 서비스입니다.

import { Injectable } from '@nestjs/common';
import { Cat } from './models/cat.model';
import { CreateCatInput } from './dto/create-cat.input';

@Injectable()
export class CatsService {
  private cats: Cat[] = [];

  findAll(): Cat[] {
    return this.cats; // 모든 고양이 데이터를 반환합니다.
  }

  create(createCatInput: CreateCatInput): Cat {
    const newCat = { id: Date.now(), ...createCatInput }; // 새로운 고양이 데이터를 생성합니다.
    this.cats.push(newCat);
    return newCat; // 생성된 고양이 데이터를 반환합니다.
  }
}

 

 

cats/models/cat.model.ts

GraphQL 타입을 정의합니다.

import { ObjectType, Field, Int } from '@nestjs/graphql';

@ObjectType() // GraphQL 객체 타입을 정의합니다.
export class Cat {
  @Field(() => Int)
  id: number; // 고양이의 ID입니다.

  @Field()
  name: string; // 고양이의 이름입니다.

  @Field()
  age: number; // 고양이의 나이입니다.

  @Field()
  breed: string; // 고양이의 품종입니다.
}

 

 

cats/dto/create-cat.input.ts

GraphQL 입력 타입을 정의합니다.

import { InputType, Field } from '@nestjs/graphql';

@InputType() // GraphQL 입력 타입을 정의합니다.
export class CreateCatInput {
  @Field()
  name: string; // 입력받을 고양이의 이름입니다.

  @Field()
  age: number; // 입력받을 고양이의 나이입니다.

  @Field()
  breed: string; // 입력받을 고양이의 품종입니다.
}

 

 

스키마 파일

Nest.js 자동으로 생성하는 schema.gql 파일의 예시:

type Cat {
  id: Int!
  name: String!
  age: Int!
  breed: String!
}

input CreateCatInput {
  name: String!
  age: Int!
  breed: String!
}

type Query {
  cats: [Cat!]!
}

type Mutation {
  createCat(createCatInput: CreateCatInput!): Cat!
}