NestJS with GraphQL

SSAD·2023년 2월 19일
0

BackEnd

목록 보기
34/44
post-thumbnail

Nest 에서 제공하는 GraphQL 빌드 방법

  • 스키마 우선(schema first)
  • 코드 우선(code first)

Nest.js 공식 홈페이지
Nest.js 코드

  • 샘플에서 코드 우선과 스키마 우선 샘플을 확인 할수 있음

1. 스키마 우선(schema first)

graphql의 schema를 먼저 정의하고, 그 schema 정의에 맞게 코드를 작성하는 방법

  • schema 작성 위해
    graphql의 data model을 나타내기 위해 만들어진 SDL(Schema Definition Language)를 사용

  • SDL은 모든 프로그래밍 언어와 독립적, 통합되는 언어
    Nestjs에서는 GraphQL 스키마를 TypeScript의 클래스 및 인터페이스 형식으로 구현

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
}),
  • 스키마 우선 접근 방식 사용하려면 옵션 객체에 typePaths 속성 추가
  • typePath 속성은 GraphQLModule이 작성할 GraphQL SDL 스키마 정의 파일을 찾아야 하는 위치

아래와 같이 직접 스키마 작성


type Query {
  cats: [Cat]
  cat(id: ID!): Cat
}

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

type Subscription {
  catCreated: Cat
}

type Owner {
  id: Int!
  name: String!
  age: Int
  cats: [Cat!]
}

type Cat {
  id: Int
  name: String
  age: Int
  owner: Owner
}

input CreateCatInput {
  name: String
  age: Int
}

schema first : graphql schema -> typescript class


2. 코드 우선(code first)

데코레이터와 TypeScript 클래스를 사용하여 먼저 작성한 Resolver를 기반으로 GraphQL 스키마를 자동 생성

  • TypeScript로만 작업하고, 언어 구문 간의 컨텍스트 전환을 피하려는 경우 유용
  • schema와 Resolver 간의 type safety를 보장
  • 코드 중복이 최소화되는 장점
GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
			autoSchemaFile: 'src/common/graphql/schema.gql',
})
  • 코드 우선 접근 방식 사용시 옵션 객체에 autoSchemaFile 속성을 추가
  • 속성 값은 자동으로 생성된 스키마가 생성될 경로

code first : typescript class -> auto graphql schema create


code First로 프로젝트 구성하기

공식문서 확인

1. 필요 패키지 설치

yarn add @nestjs/graphql @nestjs/apollo graphql apollo-server-express

2. app.module.ts 수정하기

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'src/commons/graphql/schema.gql',
    }),
  ],
})
export class AppModule {}
  • graphqlModule을 가져와 app.module에 장착
  • forRoot()메서드는 옵션 객체를 인수로 받을 수 있으며,
    ApolloServer 생성자(constructor)에 전달됨

3. 보일러 플레이트 설정하기

apis

  • API 폴더

commons

  • 모든 API에서 공통적으로 사용되는 것들을 따로 빼 놓은 폴더

module.ts

  • resolver.ts + service.ts 조립해주는 역할

resolver.ts

  • 실질적인 API 로직
  • controller.ts와 같은 파일로 이름만 다름 graphql을 사용할 경우 resolver로 사용

service.ts

  • 핵심 비지니스 로직

게시판 api 만들기

1. boards.service.ts 파일 만들기

import { Injectable } from '@nestjs/common';

@Injectable() // 의존성 주입
export class BoardService {
  sayHello() {
    return 'Hello World';
  }
}

2. boards.resolver.ts 파일 만들기


import { Query, Resolver } from '@nestjs/graphql';
import { BoardService } from './boards.service';

@Resolver()
export class BoardResolver {
  constructor(private readonly boardService: BoardService) {}

  @Query(() => String) // 리턴 타입 정의 : GraphQL API-Docs type으로 대문자 작성
  getHello():string { // Typesciprt type 지정
    return this.boardService.sayHello();
  }
}

3. boards.module.ts 파일 만들기


import { Module } from '@nestjs/common';
import { BoardResolver } from './boards.resolver';
import { BoardService } from './boards.service';

@Module({
  // imports: [],
  // controllers: [],
  providers: [BoardResolver, BoardService],
})
export class BoardModule {}

4. app.module.ts 파일 수정


import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { BoardModule } from './apis/boards/boards.module';
// import { AppController } from './app.controller';
// import { AppService } from './app.service';

@Module({
  imports: [
    BoardModule, // BoardModule 주입
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'src/commons/graphql/schema.gql',
    }),
  ],
  // controllers: [AppController],
  // providers: [AppService],
})
export class AppModule {}
profile
learn !

0개의 댓글