Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9140

【NestJS】ServiceクラスにServiceクラスを依存性注入(DI)する方法

$
0
0
はじめに 最近、実務でNestJSを書き始めました! NestJSに関する日本語の記事がまだまだ少ないので、自分用メモも兼ねてどんどん記事を書いていきたいです。 使用技術 NestJS(TypeScript) GraphQL TypeORM クラス図 HogeServiceにFugaServiceを注入して、HogeModuleを外部から利用したいというユースケースです。HogeResolverにFugaServiceを利用します。 Serviceの実装 fuga.service.ts import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import FugaEntity from 'src/entities/fuga'; @Injectable() export class FugaService { constructor( @InjectRepository(FugaEntity) private fugaRepository: Repository<FugaEntity>, // Fugaエンティティを注入 ) {} async find(id: number): Promise<FugaEntity> { return this.fugaRepository.findOne(id); } } hoge.service.ts import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import HogeEntity from 'src/entities/hoge'; import { FugaService } from './fuga.service'; @Injectable() export class HogeService { constructor( @InjectRepository(HogeEntity) private hogeRepository: Repository<HogeEntity>, // Hogeエンティティを注入 private fugaService: FugaService, // Serviceを注入 ) {} async find(id: number): Promise<HogeEntity> { const fuga = await this.fugaService.find(1); // 注入したインスタンスを利用可能に! return this.hogeRepository.findOne(id); } } 動かしてみると... [Nest] 877 - 11/28/2021, 2:45:15 AM ERROR [ExceptionHandler] Nest can't resolve dependencies of the FugaService (?). Please make sure that the argument FugaRepository at index [0] is available in the HogeModule context. Potential solutions: - If FugaRepository is a provider, is it part of the current HogeModule? - If FugaRepository is exported from a separate @Module, is that module imported within HogeModule? @Module({ imports: [ /* the Module containing FugaRepository */ ] }) 一見、これだけで動きそうなものなんですが、NestJSはmoduleで依存関係を定義してあげないとエラーが出ます。 moduleの実装 fuga.module.ts import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { FugaService } from 'src/services/fuga.service'; import FugaEntity from 'src/entities/fuga'; @Module({ imports: [TypeOrmModule.forFeature([FugaEntity])], // エンティティを明記 exports: [FugaModule, TypeOrmModule], }) export class FugaModule {} hoge.module.ts import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { HogeService } from 'src/services/hoge.service'; import HogeEntity from 'src/entities/hoge'; import { FugaModule } from './fuga.module'; import { FugaService } from 'src/services/fuga.service'; import { HogeResolver } from 'src/resolvers/hoge.resolver'; @Module({ imports: [ TypeOrmModule.forFeature([HogeEntity]), // エンティティを明記 FugaModule, // !!! 利用するモジュールを追記 !!! ], providers: [ HogeService, HogeResolver, FugaService, // !!! 利用するサービスを追記 !!! ], exports: [HogeModule, TypeOrmModule], }) export class HogeModule {} あとは、使う側にmoduleを読み込んであればOK! app.module.ts import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ApiModule } from './api.module'; import { AppController } from './app.controller'; import { AppService } from './app.service'; @Module({ imports: [ GraphQLModule.forRoot({ autoSchemaFile: true, }), TypeOrmModule.forRoot(), HogeModule, // !!! モジュールを読み込む !!! ], controllers: [AppController], providers: [AppService], }) export class AppModule {} Resolverの実装 hoge.resolver.ts import { Args, Int, Query, Resolver } from '@nestjs/graphql'; import Hoge from 'src/entities/hoge'; import { HogeService } from 'src/services/hoge.service'; @Resolver(() => Hoge) export class HogeResolver { constructor(private hogeService: HogeService) {} @Query(() => Hoge) async getHoge(@Args({ type: () => Int }) id: number) { return this.hogeService.find(id); } } コンストラクタでHogeServiceを注入して、Resolverを実装することができます。ここには、Fugserviceは出てきません! 終わりに コードをテスタブルにするために、ちゃんとService層を依存性注入(DI)するようにしたいですよね。NestJSはこれが簡単にできる仕組みを備えているので、ドキュメントをちゃんと読んで使いこなせるようになりたいです! moduleに書かないといけないことによるメリットは、正直よくわかっていないです笑。 appendix package.json "dependencies": { "@nestjs/common": "^8.0.0", "@nestjs/core": "^8.0.0", "@nestjs/graphql": "^9.0.4", "@nestjs/platform-express": "^8.0.0", "@nestjs/typeorm": "^8.0.2", "apollo-server-express": "^3.3.0", "class-transformer": "^0.4.0", "class-validator": "^0.13.1", "graphql": "^15.5.3", "graphql-tools": "^8.2.0", "pg": "^8.7.1", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.2.0", "typeorm": "^0.2.37" }, "devDependencies": { "@nestjs/cli": "^8.0.0", "@nestjs/schematics": "^8.0.0", "@nestjs/testing": "^8.0.0", "@types/express": "^4.17.13", "@types/jest": "^27.0.1", "@types/node": "^16.0.0", "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^4.28.2", "@typescript-eslint/parser": "^4.28.2", "eslint": "^7.30.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^3.4.0", "jest": "^27.0.6", "prettier": "^2.3.2", "supertest": "^6.1.3", "ts-jest": "^27.0.3", "ts-loader": "^9.2.3", "ts-node": "^10.0.0", "tsconfig-paths": "^3.10.1", "typescript": "^4.3.5" },

Viewing all articles
Browse latest Browse all 9140

Trending Articles