Quick start

Quick start

GraphQL은 API에 대한 쿼리 언어이며 기존 데이터로 쿼리를 수행하기위한 런타임입니다. 일반적인 REST API에서 발생하는 이러한 많은 문제를 해결하는 우아한 접근 방식입니다. GraphQL과 REST 사이에는 훌륭한 비교가 있습니다. 이 기사에서는 GraphQL이 무엇인지 설명하지 않고 전용 @nestjs/graphql 모듈로 작업하는 방법을 보여줍니다. 이 챕터에서는 이미 GraphQL 기본 사항에 익숙하다고 가정합니다.

GraphQLModule은 [Apollo] (https://www.apollographql.com/) 서버의 래퍼에 지나지 않습니다. 우리는 바퀴를 재발 명하지 않고 대신 사용할 준비가 된 모듈을 제공하여 GraphQL과 Nest를 함께 사용할 수 있습니다.

Installation

먼저 필요한 패키지를 설치해야합니다.

$ npm i --save @nestjs/graphql apollo-server-express graphql-tools graphql

Overview

Nest는 GraphQL 어플리케이션을 빌드하는 두 가지 방법, 즉 스키마 우선과 코드 우선을 제공합니다.

스키마 우선 접근법에서 진실의 근원은 GraphQL SDL (스키마 정의 언어)입니다. 기본적으로 서로 다른 플랫폼간에 스키마 파일을 공유 할 수 있는 언어에 구애받지 않는 방식입니다. 또한 Nest는 GraphQL 스키마 (클래스 또는 인터페이스 사용)를 기반으로 TypeScript 정의를 자동으로 생성하여 중복성을 줄입니다.

반면에 코드 우선 방식에서는 데코레이터와 TypeScript 클래스 만 사용하여 해당 GraphQL 스키마를 생성합니다. TypeScript로 독점적으로 작업하고 언어 구문 간의 컨텍스트 전환을 피하는 것이 매우 편리합니다.

Getting started

패키지가 설치되면 GraphQLModule을 등록 할 수 있습니다.

@@filename()
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({}),
  ],
})
export class ApplicationModule {}

.forRoot()메소드는 옵션 객체를 인자로 받습니다. 이러한 옵션은 기본 Apollo 인스턴스로 전달됩니다 (사용 가능한 설정에 대한 자세한 내용은 여기. 예를 들어, 놀이터를 비활성화하고 디버그 모드를 끄려면 다음 옵션을 전달하십시오.

@@filename()
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({
      debug: false,
      playground: false,
    }),
  ],
})
export class ApplicationModule {}

언급 한 바와 같이 이 모든 설정은ApolloServer 생성자로 전달됩니다.

Playground

놀이터는 그래픽 대화 형 브라우저 내 GraphQL IDE이며 기본적으로 GraphQL 서버 자체와 동일한 URL에서 사용할 수 있습니다. 애플리케이션이 백그라운드에서 실행되는 동안 웹 브라우저를 열고 http://localhost:3000/graphql로 이동하십시오 (호스트 및 포트는 구성에 따라 다를 수 있음).

Multiple endpoints

이 모듈의 또 다른 유용한 기능은 여러 엔드 포인트를 한 번에 제공하는 기능입니다. 덕분에 어떤 엔드 포인트에 어떤 모듈을 포함할지 결정할 수 있습니다. 기본적으로 GraphQL은 전체 앱에서 리졸버를 검색합니다. 모듈의 서브셋만 제한하기 위해 include 속성을 사용할 수 있습니다.

GraphQLModule.forRoot({
  include: [CatsModule],
}),

Schema first

스키마를 먼저 사용하려면 options 객체 안에typePaths 배열을 추가하면됩니다.

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
}),

typePaths 속성은 GraphQLModule이 GraphQL 파일을 찾아야하는 위치를 나타냅니다. 이러한 모든 파일은 결국 메모리에 결합되므로 스키마를 여러 파일로 분할하여 리졸버 근처에 유지할 수 있습니다.

GraphQL 유형과 해당 TypeScript 정의를 별도로 작성하면 불필요한 중복이 생성됩니다. 결국, 우리는 단일한 진실의 원천없이 결국 SDL 내에서 이루어진 각 변경으로 인해 인터페이스도 조정해야 합니다. 따라서@nestjs/graphql 패키지는 또 다른 흥미로운 기능을 제공하는데, 이는 추상 구문 트리 (AST)를 사용한 TS 정의의 자동 생성입니다. 이를 가능하게하려면 definitions 속성을 추가하면 됩니다.

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),

src/graphql.ts는 TypeScript 출력을 저장할 위치를 나타냅니다. 기본적으로 모든 유형이 인터페이스로 변환됩니다. 그러나 outputAs 속성을 class로 변경하여 대신 클래스로 전환할 수 있습니다.

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
    outputAs: 'class',
  },
}),

그러나 각 응용 프로그램 시작시 유형 정의를 생성하지 않아도됩니다. 대신, 전용 명령이 실행될 때만 완전히 제어하고 입력을 생성하는 것을 선호 할 수 있습니다. 이 경우 generate-typings.ts라고 하는 자체 스크립트를 만들 수 있습니다.

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
});

그런 다음 간단히 파일을 실행하십시오.

ts-node generate-typings

info 힌트 미리 스크립트를 컴파일하고 대신 node 실행 파일을 사용할 수도 있습니다.

감시 모드로 전환하려면 (.graphql 파일 변경시 자동으로 입력을 생성) watch 옵션을 generate()메소드에 전달하십시오.

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  watch: true,
});

완전히 작동하는 샘플은 여기에서 사용할 수 있습니다.

Code first

코드 우선 방법에서는 데코레이터와 TypeScript 클래스 만 사용하여 해당 GraphQL 스키마를 생성합니다.

Nest는이 기능을 제공하기 위해 후드 아래에서 놀라운 type-graphql 라이브러리를 사용하고 있습니다. 따라서 계속 진행하기 전에 이 패키지를 설치해야합니다.

$ npm i type-graphql

설치 과정이 완료되면, autoSchemaFile 속성을 옵션 객체에 추가 할 수 있습니다.

GraphQLModule.forRoot({
  autoSchemaFile: 'schema.gql',
}),

autoSchemaFile은 자동으로 생성된 스키마가 생성될 경로를 나타냅니다. 또한 buildSchemaOptions 속성-type-graphql 패키지에서 buildSchema()함수로 전달되는 옵션 객체를 전달할 수 있습니다.

완전히 작동하는 샘플은 여기에서 사용할 수 있습니다.

Async configuration

모듈 옵션을 미리 전달하는 대신 비동기식으로 전달하려는 경우가 종종 있습니다. 이 경우 비동기 데이터를 처리하는 몇 가지 다양한 방법을 제공하는 forRootAsync()메서드를 사용하십시오.

가능한 첫 번째 방법은 팩토리 기능을 사용하는 것입니다.

GraphQLModule.forRootAsync({
  useFactory: () => ({
    typePaths: ['./**/*.graphql'],
  }),
}),

분명히, 우리 팩토리는 다른 모든 것처럼 행동합니다 ( async일 수도 있고 inject을 통해 의존성을 주입할 수도 있습니다).

GraphQLModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    typePaths: configService.getString('GRAPHQL_TYPE_PATHS'),
  }),
  inject: [ConfigService],
}),

또는 팩토리 대신 클래스를 사용할 수 있습니다.

GraphQLModule.forRootAsync({
  useClass: GqlConfigService,
}),

위의 구성은 GraphQLModule 내에서 GqlConfigService를 인스턴스화 하고 이를 활용하여 옵션 객체를 생성합니다. GqlConfigServiceGqlOptionsFactory 인터페이스를 구현해야합니다.

@Injectable()
class GqlConfigService implements GqlOptionsFactory {
  createGqlOptions(): GqlModuleOptions {
    return {
      typePaths: ['./**/*.graphql'],
    };
  }
}

GraphQLModule 내에 GqlConfigService가 작성되는 것을 막고 다른 모듈에서 가져온 제공자를 사용하려면useExisting 구문을 사용할 수 있습니다.

GraphQLModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
}),

하나의 중요한 차이점으로 useClass와 동일하게 작동합니다. GraphQLModule은 가져온 모듈을 조회하여 이미 생성된 ConfigService를 자체적으로 인스턴스화 하는 대신 재사용합니다.

Last updated