Open10

@nestjs/graphql 入門

odanodan

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 firstschema first がある

odanodan

http://localhost:3000/graphqlGraphQL 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)

なにかコードが足りてないっぽい気がするので一旦次に行く

odanodan
GraphQLModule.forRoot({
  include: [CatsModule],
}),

って書くとスキャンするモジュールを制限できる

こういう機能というか思想大事、途中から新しいアーキテクチャを導入しやすくなる

odanodan

Code First から試してみる

サンプルはここ
https://github.com/nestjs/nest/tree/master/sample/23-graphql-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 して事なきを得た

https://github.com/odan-sandbox/nestjs-graphql-sandbox/blob/11c826003af3bfa12b0f036613d5a4192d225692/src/recipes/recipes.resolver.ts

一部を写経して Playground からクエリを投げることに成功

odanodan

Schema First を試す

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),

と書く必要がある
typePaths にスキーマを定義、definitions はスキーマから TS のコードを自動生成する先らしい

写経は面倒なのでしない
例を見ると、これがスキーマで
https://github.com/nestjs/nest/blob/master/sample/12-graphql-schema-first/src/cats/cats.graphql

これが自動生成される TS のコードらしい
https://github.com/nestjs/nest/blob/master/sample/12-graphql-schema-first/src/graphql.schema.ts

resolver の実装はこれ
https://github.com/nestjs/nest/blob/master/sample/12-graphql-schema-first/src/cats/cats.resolver.ts

odanodan

Code First vs Schema First 考察

TS を書き慣れている側の人間からすると Code First のほうが扱いやすそう。あとTS を中心にすると class-validator とか使った validation を設定しやすいはず。

Schema First はバックエンド同士の通信に GraphQL を使うなど、スキーマが中心なアーキテクチャに刺さりそう。
あと Prism と組み合わせることもできるのかな。できるなら RDB のスキーマと Web API のスキーマを同時に定義できるので楽そう

実現したいアーキテクチャに対してどっちを選ぶか?という話になるので優劣は特になさそうな気がする

golang とか他の言語だとどっちが主流なんだろう