ライブラリのインストール
shell
npm i @nestjs/graphql @nestjs/apollo @apollo/server graphql
バリデーションライブラリのインストール
shell
npm i --save class-validator class-transformer
main.ts
でバリデーションを設定します。
main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const configService = app.get(ConfigService);
const appPort = configService.get<number>('app.port');
app.useGlobalPipes(new ValidationPipe());
await app.listen(appPort);
console.log(`App is running on: ${await app.getUrl()}`);
}
bootstrap();
GraphQL の依存関係を定義
app.module.ts
に GraphQLModule.forRoot
を import します。 あえてその他のモジュールの import も書いていますが、 GraphQLModule.forRoot<ApolloDriverConfig>
の部分が今回の主題です。
app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule, ConfigService } from '@nestjs/config';
import configration from './config/configration';
import { TypeOrmModule } from '@nestjs/typeorm';
import { NotesModule } from './notes/notes.module';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [configration],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'mariadb',
host: configService.get<string>('database.host'),
port: configService.get<number>('database.port'),
username: configService.get<string>('database.username'),
password: configService.get<string>('database.password'),
database: configService.get<string>('database.database'),
synchronize: configService.get<boolean>('database.synchronize'),
autoLoadEntities: true,
charset: 'utf8mb4',
}),
inject: [ConfigService],
}),
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: 'src/schema.gql',
sortSchema: true,
}),
NotesModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
DTO を作成する
GraphQL のクエリの Input, Output を定義します。
src/notes/dto/notes.dto.ts
import { ArgsType, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { IsInt, Max, Min } from 'class-validator';
@ArgsType()
export class NotesPayload {
@IsInt()
@Min(0)
@Field(() => Int)
skip: number;
@Field(() => Int)
@Min(1)
@Max(50)
take: number;
}
@ObjectType({ description: 'ノート' })
export class NotesOutput {
@Field(() => ID)
id: string;
@Field(() => String)
title: string;
}
Resolver を作成する
パラメータを受け取って、Output で定義した型で値を返します。
src/notes/notes.resolver.ts
import { Args, Query, Resolver } from '@nestjs/graphql';
import { NotesOutput, NotesPayload } from './dto/notes.dto';
@Resolver()
export class NotesResolver {
@Query(() => [NotesOutput], { name: 'notes' })
notes(@Args() notesArgs: NotesPayload): NotesOutput[] {
console.log('サービスに渡してデータを取得します - notesArgs:', notesArgs);
return [
{
id: 'uuid1',
title: 'note1',
},
];
}
}
サブモジュールの providers に Resolver を設定する
src/notes/nodes.module.ts
import { TypeOrmModule } from '@nestjs/typeorm';
import { NoteEntity } from './entities/note.entity';
import { Module } from '@nestjs/common';
import { NotesResolver } from './notes.resolver';
@Module({
imports: [TypeOrmModule.forFeature([NoteEntity])],
providers: [NotesResolver],
})
export class NotesModule {}
この NotesModule
はルートモジュール( app.module.ts
)で import します。
クエリを投げてみる
Query
query notes(
$skip: Int!,
$take: Int!
) {
notes(
skip: $skip,
take: $take
) {
id
title
}
}
Variables
{"skip": 1, "take": 5}
上記のクエリを投げると、結果が返って来ます。
結果
{
"data": {
"notes": [
{
"id": "uuid1",
"title": "note1"
}
]
}
}
http://localhost:3000/graphql
向けに POST
リクエストを投げてます。
Thunder Client のスクショです。