※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。


【Nest.js】GraphQLのTypeScript型定義の自動生成方法まとめ

GraphQL interface TypeScript Node.js nest.js

投稿日:2023年2月18日

このエントリーをはてなブックマークに追加
Nest.jsでは特定のデコレータをつけたTypeScriptクラスから簡単にGraphQLのAPIを作成することができます。この記事では、作成したGraphQL APIのTypeScript型定義を自動で生成する方法について詳細に解説します。

はじめに

この記事について

Nest.jsTypeScriptを完全にサポートしているサーバーサイドフレームワークです。

このフレームワークは比較的簡単にGraphQLのAPIを構築することができます。そのパッケージでデフォルトでサポートされている機能の中にTypeScript型定義自動生成機能があるのですが、フロントのコードがTypeScriptである場合この機能が非常に効力を発揮します。

この記事ではGraphQL APIのTypeScript型定義自動生成機能について実際のユースケースを交えて解説して行きます。

環境

この記事のコードは以下の環境で確認されました。

  • Apple M1 Max MacBook Pro
  • macOS 13.0.1(22A400)
  • nodejs v18.14.0
  • npm version 9.3.1
  • nestjs version 9.0.0

参考URL


実践

サンプルの環境について

ここで説明に使用するサンプルの環境について説明します。

下のようにサーバーサイドのNest.jsアプリケーションと、フロントサイドのNext.jsアプリケーションが、同じディレクトリに配置してあります。

プロジェクトのディレクトリ構造
.
├── nest-app
└── next-app

Nest.jsアプリケーションの中にはcatという名前でGraphQL用のサンプルのモジュールが用意しています。

(Next.jsの側の構造は今回はあまり関係ないので一旦省略します)

ではサンプルの説明はここまでにして実際の実装に入っていきましょう!

実践

では早速Nest.jsアプリケーションの設定を修正して、Next.jsアプリケーションのnest-generatedというディレクトリにgraphql.tsというファイル名で、サンプルで用意したGraphQL APIのTypeScript型定義を生成してみましょう。


公式のドキュメントにあるようにApolloDriverConfigのプロパティのdefinitionsに対して必要な情報を渡すことで、Nest.jsのサーバー起動時に自動生成を走らせることができます。

nest-app/src/app.module.ts
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { join } from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './cats/cats.module';

// 型定義を作成する先を定義
const GQL_TS_TYPE_DIR = '../next-app/nest-generated';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      debug: true,
      playground: true,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
      sortSchema: true,
      definitions: {
        path: join(process.cwd(), GQL_TS_TYPE_DIR, 'graphql.ts'), // TypeScriptの型定義ファイルを作成,
      },
    }),
    CatsModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

では開発用サーバーを起動してみます。

ターミナル
$ npm run start:dev

生成されるTypeScript型定義は以下のようなものです。

next-app/nest-generated/graphql.ts
/*
 * -------------------------------------------------------
 * THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
 * -------------------------------------------------------
 */

/* tslint:disable */
/* eslint-disable */

export interface Cat {
    age: number;
    name: string;
    ownerName?: Nullable<number>;
}

export interface IQuery {
    cat(): Cat | Promise<Cat>;
}

type Nullable<T> = T | null;

かなり良い感じですね!

補足:環境変数ごとに出力設定を変更する

出力は開発環境のみ使用して、プロダクション環境では出力しないようにしたい時など、useFactory()ConfigModule を使用して使い分けをすると良いかもしれませんね。

nest-app/src/app.module.ts
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { GraphQLModule } from '@nestjs/graphql';
import { join } from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [
    ConfigModule.forRoot(),
    GraphQLModule.forRootAsync({
      driver: ApolloDriver,
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => {
        // 環境情報を取得
        const nodeEnv = configService.get('NODE_ENV', 'development');
        if (nodeEnv === 'development') {
          // 出力先を取得
          const gqlTsTypeDir = configService.getOrThrow('GQL_TS_TYPE_DIR');
          return {
            driver: ApolloDriver,
            debug: true,
            playground: true,
            autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
            sortSchema: true,
            definitions: {
              path: join(process.cwd(), gqlTsTypeDir, 'graphql.ts'), // TypeScriptの型定義ファイルを作成,
            },
          };
        } else {
          return {
            driver: ApolloDriver,
            debug: false,
            playground: false,
            autoSchemaFile: true,
          };
        }
      },
      inject: [ConfigService],
    }),
    CatsModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
このエントリーをはてなブックマークに追加


関連記事

記事へのコメント