@nestjs/graphql 入門
https://github.com/nestjs/typescript-starter をベースにリポジトリを作る
作った
Nest offers two ways of building GraphQL applications, the code first and the schema first methods. You should choose the one that works best for you. Most of the chapters in this GraphQL section are divided into two main parts: one you should follow if you adopt code first, and the other to be used if you adopt schema first.
code first
と schema first
がある
As mentioned, these options will be forwarded to the ApolloServer constructor.
GraphQLModule.forRoot
の引数は ApolloServer
にフォワードされる
たしかにコードを見ると
import { Config } from 'apollo-server-core';
が使われている
http://localhost:3000/graphql
に GraphQL playground
が立ち上がる
試しに yarn start:dev
するとエラーが発生した
[19:07:40] Starting compilation in watch mode...
[19:07:43] Found 0 errors. Watching for file changes.
[Nest] 39623 - 2021/07/14 19:07:44 LOG [NestFactory] Starting Nest application...
[Nest] 39623 - 2021/07/14 19:07:44 LOG [InstanceLoader] AppModule dependencies initialized +42ms
[Nest] 39623 - 2021/07/14 19:07:44 LOG [InstanceLoader] GraphQLSchemaBuilderModule dependencies initialized +0ms
[Nest] 39623 - 2021/07/14 19:07:44 LOG [InstanceLoader] GraphQLModule dependencies initialized +1ms
[Nest] 39623 - 2021/07/14 19:07:44 LOG [RoutesResolver] AppController {/}: +8ms
[Nest] 39623 - 2021/07/14 19:07:44 LOG [RouterExplorer] Mapped {/, GET} route +4ms
/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/apollo-server-core/src/ApolloServer.ts:588
throw Error(
^
Error: Apollo Server requires either an existing schema, modules or typeDefs
at ApolloServer.constructSchema (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/apollo-server-core/src/ApolloServer.ts:588:13)
at new ApolloServerBase (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/apollo-server-core/src/ApolloServer.ts:295:54)
at new ApolloServer (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/apollo-server-express/src/ApolloServer.ts:50:5)
at GraphQLModule.registerExpress (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/@nestjs/graphql/dist/graphql.module.js:128:30)
at GraphQLModule.registerGqlServer (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/@nestjs/graphql/dist/graphql.module.js:113:18)
at GraphQLModule.onModuleInit (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/@nestjs/graphql/dist/graphql.module.js:100:20)
at Object.callModuleInitHook (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/@nestjs/core/hooks/on-module-init.hook.js:51:9)
at NestApplication.callInitHook (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/@nestjs/core/nest-application-context.js:169:13)
at NestApplication.init (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/@nestjs/core/nest-application.js:97:9)
at NestApplication.listen (/Users/odan/source/github.com/odan-sandbox/nestjs-graphql-sandbox/node_modules/@nestjs/core/nest-application.js:156:33)
なにかコードが足りてないっぽい気がするので一旦次に行く
GraphQLModule.forRoot({
include: [CatsModule],
}),
って書くとスキャンするモジュールを制限できる
こういう機能というか思想大事、途中から新しいアーキテクチャを導入しやすくなる
Code First から試してみる
サンプルはここ
写経を進めてある程度まで進んだところで次のエラーが発生した
Error: You must `await server.start()` before calling `server.applyMiddleware()`
ググると https://stackoverflow.com/a/68354663 がヒットする。最近発生した不具合らしく、apollo-server-express のバージョンを下げると動くらしい
[at] DimDimi4 downgrade to Apollo v2. Nest v8 shouldn't be used in combination with Apollo v3
https://github.com/nestjs/graphql/pull/1627#issuecomment-878891378
yarn add apollo-server-express@^2.25.2
して事なきを得た
一部を写経して Playground からクエリを投げることに成功
Schema First を試す
GraphQLModule.forRoot({
typePaths: ['./**/*.graphql'],
definitions: {
path: join(process.cwd(), 'src/graphql.ts'),
},
}),
と書く必要がある
typePaths
にスキーマを定義、definitions
はスキーマから TS のコードを自動生成する先らしい
写経は面倒なのでしない
例を見ると、これがスキーマで
これが自動生成される TS のコードらしい
resolver の実装はこれ
Code First vs Schema First 考察
TS を書き慣れている側の人間からすると Code First のほうが扱いやすそう。あとTS を中心にすると class-validator とか使った validation を設定しやすいはず。
Schema First はバックエンド同士の通信に GraphQL を使うなど、スキーマが中心なアーキテクチャに刺さりそう。
あと Prism と組み合わせることもできるのかな。できるなら RDB のスキーマと Web API のスキーマを同時に定義できるので楽そう
実現したいアーキテクチャに対してどっちを選ぶか?という話になるので優劣は特になさそうな気がする
golang とか他の言語だとどっちが主流なんだろう
次やりたい
- Apollo Client との組み合わせ
- Prism との組み合わせ
- Hasura との組み合わせ
- https://www.graphql-code-generator.com/docs/getting-started/installation