NestJS中如何在两个不同路由下共享同一FoodModule
问题根源
NestJS模块默认是单例模式,FoodModule被导入后只会初始化一次。你在RouterModule中重复将同一个FoodModule挂载到不同父路由下时,后注册的路由配置会覆盖之前的,因此只有最后一个(/dogs/food)生效。
解决方案:拆分服务与控制器,子模块创建专属路由控制器
核心思路是将Food的业务逻辑抽为共享服务,在CatsModule和DogsModule中分别创建专属控制器,绑定各自的路由前缀,同时复用同一个FoodService。
步骤1:重构FoodModule,仅保留共享服务
修改food/food.module.ts,移除控制器并导出服务:
import { Module } from '@nestjs/common'; import { FoodService } from './food.service'; @Module({ providers: [FoodService], exports: [FoodService], // 导出服务供其他模块注入 }) export class FoodModule {}
步骤2:在CatsModule中创建专属Food控制器
新建cats/cats-food.controller.ts,绑定/cats/food路由:
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; import { FoodService } from '../food/food.service'; @Controller('cats/food') export class CatsFoodController { constructor(private readonly foodService: FoodService) {} @Post() create(@Body() createFoodDto) { return this.foodService.create(createFoodDto); } @Get() findAll() { return this.foodService.findAll(); } @Get(':id') findOne(@Param('id') id: string) { return this.foodService.findOne(+id); } @Patch(':id') update(@Param('id') id: string, @Body() updateFoodDto) { return this.foodService.update(+id, updateFoodDto); } @Delete(':id') remove(@Param('id') id: string) { return this.foodService.remove(+id); } }
更新cats/cats.module.ts,导入FoodModule并添加新控制器:
import { Module } from '@nestjs/common'; import { CatsService } from './cats.service'; import { CatsController } from './cats.controller'; import { FoodModule } from '../food/food.module'; import { CatsFoodController } from './cats-food.controller'; @Module({ imports: [FoodModule], controllers: [CatsController, CatsFoodController], providers: [CatsService], }) export class CatsModule {}
步骤3:在DogsModule中重复相同操作
新建dogs/dogs-food.controller.ts,绑定/dogs/food路由:
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; import { FoodService } from '../food/food.service'; @Controller('dogs/food') export class DogsFoodController { constructor(private readonly foodService: FoodService) {} @Post() create(@Body() createFoodDto) { return this.foodService.create(createFoodDto); } @Get() findAll() { return this.foodService.findAll(); } @Get(':id') findOne(@Param('id') id: string) { return this.foodService.findOne(+id); } @Patch(':id') update(@Param('id') id: string, @Body() updateFoodDto) { return this.foodService.update(+id, updateFoodDto); } @Delete(':id') remove(@Param('id') id: string) { return this.foodService.remove(+id); } }
更新dogs/dogs.module.ts:
import { Module } from '@nestjs/common'; import { DogsService } from './dogs.service'; import { DogsController } from './dogs.controller'; import { FoodModule } from '../food/food.module'; import { DogsFoodController } from './dogs-food.controller'; @Module({ imports: [FoodModule], controllers: [DogsController, DogsFoodController], providers: [DogsService], }) export class DogsModule {}
步骤4:简化AppModule配置
移除RouterModule中关于food的配置,同时删除直接导入的FoodModule(子模块已导入):
import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { CatsModule } from './cats/cats.module'; import { DogsModule } from './dogs/dogs.module'; @Module({ imports: [CatsModule, DogsModule], controllers: [AppController], providers: [AppService], }) export class AppModule {}
验证效果
启动应用后,控制台会输出以下路由映射:
/cats/food的所有CRUD路由/dogs/food的所有CRUD路由
两个路由将共享FoodService的业务逻辑,符合预期需求。
内容的提问来源于stack exchange,提问作者devesh-verma
相关产品推荐
相关产品推荐

