はじめに
自分なりに、どう作っていくかってのを記述したメモです。
追加開発とかなら4以降を手順通りするか、コピペすれば流用していけるはず。
※共通化部分をどうしていくかは課題。
環境
"@nestjs/common": "^8.0.0",
"@nestjs/core": "^8.0.0",
"@nestjs/graphql": "^9.0.4",
"@nestjs/cli": "^8.0.0",
全体の流れ
- プロジェクト作成
- GraphQLのライブラリ導入
- 初期起動確認
- GraphQL用のモジュール作成
- モジュール
- リゾルバー
- サービス
- モデル(スキーマのtype)
- ロジックの実装
- 起動確認
- Queryの実行
プロジェクト作成
nest new nest-graphql-new
cd nest-graphql-new
※package管理はyarnを利用
ライブラリ導入
yarn add @nestjs/graphql graphql apollo-server-express
初期起動確認
yarn start
# ストップ
Ctrl + c
モジュール作成
https://docs.nestjs.com/cli/usages#nest-generate
nest g module recipes
nest g resolver recipes --no-spec
nest g service recipes --no-spec
nest g class recipes/models/recipe --no-spec
ロジック実装
app.modules.ts
- コメント化のみ
- RecipesModuleは自動で入る
import { Module } from '@nestjs/common';
// import { AppController } from './app.controller';
// import { AppService } from './app.service';
import { RecipesModule } from './recipes/recipes.module';
@Module({
imports: [
RecipesModule,
],
// controllers: [AppController],
// providers: [AppService],
})
export class AppModule {}
※app.controllerとserviceは除外した。(Rest的にも使う時はあっても良い)
recipes/recipes.modules.ts
- GraphQLModuleの定義追加
import { Module } from '@nestjs/common';
import { RecipesResolver } from './recipes.resolver';
import { RecipesService } from './recipes.service';
import { GraphQLModule } from '@nestjs/graphql';
@Module({
providers: [RecipesResolver, RecipesService],
imports: [
GraphQLModule.forRoot({
installSubscriptionHandlers: true,
autoSchemaFile: 'schema/recipe.gql',
// debug: true,
// playground: true,
}),
],
})
export class RecipesModule {}
recipes/models/recipe
- モデル定義、データ型のようなもの
import { Field,ID, ObjectType} from '@nestjs/graphql';
@ObjectType()
export class Recipe {
@Field(type =>ID)
id: string;
@Field()
name: string;
}
recpes/recipes.service.ts
- データ取得のロジック実装。
- ここで外部API使ってデータ取得したりしなかったり。
import { Injectable } from '@nestjs/common';
import { Recipe } from './models/recipe';
@Injectable()
export class RecipesService {
async findOneById(id: string): Promise<Recipe> {
const recipe = new Recipe();
recipe.id = '1234';
recipe.name = 'name';
return recipe;
}
}
※サービス実装(疎通用でテストデータ設定)
recpes/recipes.resolver.ts
- クライアントのからの呼び出し定義的な。
import { Resolver, Args, Query } from '@nestjs/graphql';
import { RecipesService } from './recipes.service';
import { Recipe } from './models/recipe';
@Resolver(of => Recipe)
export class RecipesResolver {
constructor(private readonly recipesService: RecipesService) {
}
@Query(returns => Recipe)
async recipe(@Args('id') id: string): Promise<Recipe> {
return await this.recipesService.findOneById(id);
}
}
起動確認
yarn start
yarn run v1.22.11
$ nest start
[Nest] 29754 - 09/24/2021, 11:31:53 AM LOG [NestFactory] Starting Nest application...
[Nest] 29754 - 09/24/2021, 11:31:53 AM LOG [InstanceLoader] AppModule dependencies initialized +17ms
[Nest] 29754 - 09/24/2021, 11:31:53 AM LOG [InstanceLoader] RecipesModule dependencies initialized +1ms
[Nest] 29754 - 09/24/2021, 11:31:53 AM LOG [InstanceLoader] GraphQLSchemaBuilderModule dependencies initialized +0ms
[Nest] 29754 - 09/24/2021, 11:31:53 AM LOG [InstanceLoader] GraphQLModule dependencies initialized +0ms
[Nest] 29754 - 09/24/2021, 11:31:53 AM LOG [NestApplication] Nest application successfully started +44ms
■play ground起動
http://localhost:3000/graphql
まとめ
基礎の進め方としては、こんな感じで開発していけそう。
GraphQLModule.forRootこの定義が、AppModuleに定義するべきかどうかってのがあるが、上記のようにすると、モジュール単位で分離していけそう。
モデル内で他モジュールのモデル利用とか考えると、モデルは外に出した方が良いのかも。
この辺りは、実装進めてみて考える。ひとまず叩き台としてのメモです。