NestJSでGraphQLを試してみました

こんにちは中川です。

普段はREST APIばかりさわっているため、ちょっと他のAPIもと思うこの頃、
今回は NestJSでGraphQLを試してみました。

参考

やってみる

まずは、nestコマンドでプロジェクトを作成します。

npm i -g @nestjs/cli
nest new project
cd project

つぎに、GraphQL関連のパッケージをインストールします。

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

サンプルで使うcatsモジュールもnestコマンドでさくっと作ってしまいます。

nest generate module cats
nest generate service cats
nest generate resolver cats

続いて、CatsのGraphQL定義を作成します。
今回は軽く試してみるということで、公式チュートリアルからクエリ系のみに絞って定義します。

  
type Query {
  getCats: [Cat]
  cat(id: ID!): Cat
}
type Cat {
  id: Int
  name: String
  age: Int
}

さて、ここからはコードを編集していきます。

まずはappモジュールにGraphQLModuleを追加importして、
以下の各オプションを指定します。

  • typePaths: ディレクトリ内の*.graphqlファイルを読み込むようにしています
  • definitions: tsファイルの生成先を指定してしています
  • playground: ブラウザからGraphQLの実行を確認できる環境を有効にしています
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql'
import { join } from 'path';
import { CatsModule } from './cats/cats.module';
@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      definitions: {
        path: join(process.cwd(), 'src/graphql.schema.ts')
      },
      playground: true
    }),
    CatsModule
  ]
})
export class AppModule {}

これで、アプリを実行すると、graphqlファイルから自動でTypeScriptの型定義ファイルが、
src/graphql.schema.ts に生成されます。

/** ------------------------------------------------------
 * THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
 * -------------------------------------------------------
 */
/* tslint:disable */
export interface Cat {
    id?: number;
    name?: string;
    age?: number;
    weight?: number;
}
export interface IQuery {
    getCats(): Cat[] | Promise<Cat[]>;
    cat(id: string): Cat | Promise<Cat>;
}

CatsResolver で利用するために、 CatsService を作成します。

import { Injectable } from '@nestjs/common';
import { Cat } from 'src/graphql.schema';
@Injectable()
export class CatsService {
    private readonly cats: Cat[] = [
        {id: 1, name: 'Cat1', age: 5},
        {id: 2, name: 'Cat2', age: 10}
    ]
    findAll() {
        return this.cats
    }
    findOneById(id: number) {
        return this.cats.find(cat => cat.id === id)
    }
}

後は CatsResolver に、クエリのメソッドを定義すれば完成です。

import { Resolver, Args, Query } from '@nestjs/graphql';
import { CatsService } from './cats.service';
import { ParseIntPipe } from '@nestjs/common';
@Resolver('Cats')
export class CatsResolver {
    constructor(private readonly catsService: CatsService) {}
    @Query()
    getCats() {
        return this.catsService.findAll()
    }
    @Query('cat')
    findOneById(
        @Args('id', ParseIntPipe)
        id: number,
    ) {
        return this.catsService.findOneById(id)
    }
}

アプリを実行して、ブラウザで http://localhost:3000/graphql にアクセスすると、
Playgroundでクエリを実行して結果を確認することができます。

f:id:nakagawayoshiki:20191220111348p:plain
Playground

おわりに

今回は NestJSでGraphQLを試してみました。
GraphQLスキーマを作れば、自動でドキュメントや型定義を生成してくれるので間違いもなく、
REST APIと比べてもとても手軽な印象でした。

また色々と試してみたいと思います。