【NestJS】他のモジュールにあるサービスを使いたい（SharedModuleを作る）

REST APIを作るうえで、リソース単位でモジュールを固めるのが基本かと思います。
でも、他のリソースも見る必要が出てきたらどうしましょう？

そんな時、NestJSでは他のモジュールをインポートして簡単に使うことができます！


[公式](https://docs.nestjs.com/modules#shared-modules)でSharedModuleについて記載されてますので、実際に使ってみたいと思います。

# NestJSプロジェクトを生成

```
nest new nest-test
```

# モジュールを追加

今回はmodule1とmodule2を作成し、module2でmodule1のサービスを使ってみたいと思います。

## モジュール１の追加

- src/module1ディレクトリ内に以下のファイルを追加
    - module1.service.ts
    - module1.controller.ts
    - module1.module.ts


```module1.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class Module1Service {
  getHello(): string {
    return 'Hello Shared Service!';
  }
}
```

```module1.controller.ts
import { Controller, Get } from '@nestjs/common';
import { Module1Service } from './module1.service';

@Controller('module1')
export class Module1Controller {
  constructor(private readonly module1Service: Module1Service) {}

  @Get()
  getHello(): string {
    return this.module1Service.getHello();
  }
}
```

```module1.module.ts
import { Module } from '@nestjs/common';
import { Module1Controller } from './module1.controller';
import { Module1Service } from './module1.service';

@Module({
  imports: [],
  controllers: [Module1Controller],
  providers: [Module1Service],
  exports: [Module1Service],
})
export class Module1Module {}
```

- ポイントは`module1.module.ts`で`exports: [Module1Service]`することです。
    - providerで提供しているものはexportsに指定することで、外部で参照できるようになります
   

## モジュール２の追加

- src/module2ディレクトリ内に以下のファイルを追加
    - module2.service.ts
    - module2.controller.ts
    - module2.module.ts


```module2.service.ts
import { Injectable } from '@nestjs/common';
import { Module1Service } from 'src/module1/module1.service';

@Injectable()
export class Module2Service {
    constructor(private readonly module1Service: Module1Service) { }

    getHello(): string {
        return this.module1Service.getHello();
    }
}
```

- module1Serviceをインジェクションします


```module2.controller.ts
import { Controller, Get } from '@nestjs/common';
import { Module2Service } from './module2.service';

@Controller('module2')
export class Module2Controller {
  constructor(private readonly module2Service: Module2Service) {}

  @Get()
  getHello(): string {
    return this.module2Service.getHello();
  }
}
```

```module2.module.ts
import { Module } from '@nestjs/common';
import { Module2Controller } from './module2.controller';
import { Module2Service } from './module2.service';
import { Module1Module } from 'src/module1/module1.module';

@Module({
  imports: [Module1Module],
  controllers: [Module2Controller],
  providers: [Module2Service],
})
export class Module2Module {}
```

- こちらでは`imports: [Module1Module]`でモジュール１をインポートします
    - これでモジュール１でexportsに指定しているものが使えるようになります。


## AppModuleに追加

```app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Module2Module } from './module2/module2.module';
import { Module1Module } from './module1/module1.module';

@Module({
    imports: [
        Module1Module,
        Module2Module
    ],
    controllers: [AppController],
    providers: [AppService],
})
export class AppModule { }
```


# 動作確認

サーバーを起動します

```
npm start
```

## モジュール１にアクセス

`http://localhost:3000/module1`にアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/41827686-b8f4-3ab1-3760-eda9285284e1.png)

## モジュール２にアクセス

`http://localhost:3000/module2`にアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/51e01ea0-de79-538c-21fa-39c98fb9afca.png)



# まとめ

簡単にサービスを共用できました！
適切にモジュール分割していればきれいに作れると思うので、活用しましょう！！



# 参考
[Modules(Shared modules) | NestJS](https://docs.nestjs.com/modules#shared-modules)