> For the complete documentation index, see [llms.txt](https://jakekwak.gitbook.io/nestjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jakekwak.gitbook.io/nestjs/graphql/untitled.md).

# Quick start

## Quick start

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

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

## Installation

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

```bash
$ 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`을 등록 할 수 있습니다.

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

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

`.forRoot()`메소드는 옵션 객체를 인자로 받습니다. 이러한 옵션은 기본 Apollo 인스턴스로 전달됩니다 (사용 가능한 설정에 대한 자세한 내용은 [여기](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options%20-lt-ApolloServer-gt). 예를 들어, 놀이터를 비활성화하고 디버그 모드를 끄려면 다음 옵션을 전달하십시오.

```typescript
@@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` 속성을 사용할 수 있습니다.

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

## Schema first

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

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

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

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

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

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

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

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

```typescript
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',
});
```

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

```bash
ts-node generate-typings
```

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

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

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

완전히 작동하는 샘플은 [여기](https://github.com/nestjs/nest/tree/master/sample/12-graphql-apollo)에서 사용할 수 있습니다.

## Code first

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

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

```bash
$ npm i type-graphql
```

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

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

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

완전히 작동하는 샘플은 [여기](https://github.com/nestjs/nest/tree/master/sample/23-type-graphql)에서 사용할 수 있습니다.

## Async configuration

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

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

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

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

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

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

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

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

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

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

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

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