NestJS + MySQL + Prisma + GraphQL環境の構築
タイトルの組み合わせで、GraphQLのデータ取得Queryが実行可能なところまで構築する。
なお、GraphQLの実装はコードファーストとスキーマファーストの2種類があるが、今回はコードファーストで実装する。
※Prismaはライブラリの更新速度が早く、コマンドが陳腐化している可能性があるため注意
コマンド実行後のエラー等に最新verでの実行方法の補足が表示されるため、エラーが出た場合はそちらを参考にする
環境
- NestJS 7系
Init Nest
パッケージ追加とプロジェクトの初期化を行う。
npm i -g @nestjs/cli
nest new app-name
Init MySQL
MySQLを起動するdocker-compose.yml
を用意する。
※開発用途で脆弱な設定であるため注意。
version: '3.8' services: db: image: mysql:8 container_name: db environment: MYSQL_ROOT_PASSWORD: password ports: - '3306:3306' command: --default-authentication-plugin=mysql_native_password volumes: - ./mysql:/var/lib/mysql
MySQLを起動する。
docker-compose up
Init Prisma
Prismaを設定する。
yarn add --dev prisma
npx prisma init
生成されたschema.prisma
のprovider
をMySQLに変更。
- provider = "postgresql" + provider = "mysql"
また、データベースの初期化用にIDだけのユーザーモデルを追記する。
model User { id String @id @default(uuid()) }
.env
に接続情報を定義
# Database DATABASE_URL="mysql://root:password@localhost/db"
マイグレーションを実行する。
npx prisma migrate dev
nestjsでPrismaのServiceを用意する。
nest g module prisma nest g service prisma
作成したprisma.service.ts
を下記のように修正。
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy { async onModuleInit() { await this.$connect(); } async onModuleDestroy() { await this.$disconnect(); } }
prisma.module.ts
でPrismaService
をエクスポートする。
import { Module } from '@nestjs/common'; import { PrismaService } from './prisma.service'; @Module({ providers: [PrismaService], exports: [PrismaService], }) export class PrismaModule {}
GraphQL設定
必要なライブラリをインストールする。
yarn add @nestjs/graphql graphql-tools graphql apollo-server-express
app.module.ts
にGraphQLModuleのインポート設定を追記。
import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { Request, Response } from 'express'; import { join } from 'path'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { PrismaModule } from './prisma/prisma.module'; @Module({ imports: [ GraphQLModule.forRoot({ autoSchemaFile: join(process.cwd(), 'src/schema.gql'), // Resolverでexpressのreq/resを利用する場合設定する // context: ({ req, res }): { req: Request; res: Response } => ({ // req, // res, // }), // corsの設定が必要な場合 // cors: { // origin: process.env.ORIGINS?.split(','), // credentials: true, // }, debug: process.env.NODE_ENV === 'production' ? false : true, playground: process.env.NODE_ENV === 'production' ? false : true, }), PrismaModule, ], controllers: [AppController], providers: [AppService], }) export class AppModule {}
コードファーストの定義を簡略化するため、nest-cli.json
に下記設定を追記。
{ "collection": "@nestjs/schematics", "sourceRoot": "src", "compilerOptions": { "plugins": [ { "name": "@nestjs/graphql/plugin", "options": { "typeFileNameSuffix": [ ".input.ts", ".args.ts", ".entity.ts", ".model.ts" ] } } ] } }
GraphQL実装
User
モデルのデータを取得できるリゾルバを作成する。
nest g mo Users nest g resolver Users nest g service Users
users.module.ts
のimports
にPrismaModule
を追記。
+ imports: [PrismaModule]
entityを定義する。
touch src/users/user.entity.ts
import { ObjectType } from '@nestjs/graphql'; @ObjectType() export class User { id!: string; }
users.service.ts
にPrismaを使用してユーザーを全件取得するメソッドを定義する。
import { Injectable } from '@nestjs/common'; import { PrismaService } from 'src/prisma/prisma.service'; @Injectable() export class UsersService { constructor(private readonly prisma: PrismaService) {} findAll() { return this.prisma.user.findMany(); } }
users.resolver.ts
にユーザーを全件取得するリゾルバを定義する。
import { Query, Resolver } from '@nestjs/graphql'; import { User } from './user.entity'; import { UsersService } from './users.service'; @Resolver() export class UsersResolver { constructor(private readonly usersService: UsersService) {} @Query(() => [User], { name: 'users' }) findAll(): Promise<User[]> { return this.usersService.findAll(); } }
app.module.ts
にUsersModule
のimportを追加する。
... imports: [ ... UsersModule, ], ...
Prisma Studioを用いて、Webインターフェースから適当にUserを追加する。
npx prisma studio
# デフォルトでhttp://localhost:5555でPrisma Studioが起動するので、ユーザーテーブル選択後、Add recordからデータを追加する
接続確認
実際にアプリケーションを起動し、GraphQL Playgroundからユーザーデータを取得する。
yarn start:dev
アプリケーションが起動したらhttp://localhost:3000/graphql
にアクセスし、下記クエリを実行する。
query { users { id } }
データが正常に取得できればセットアップ完了。
{ "data": { "users": [ { "id": "4d3147b8-0b2d-4c6b-a54d-b9bbb2d627b5" }, { "id": "590ee871-e7ba-42d0-be0c-ce55377112cf" }, { "id": "9177215b-b055-4140-84bf-e89233d1ef49" } ] } }