NestJS with TypeORM:使用自定义存储库时,是否还需要服务?

NestJS with TypeORM: When using custom repository, is a service needed anymore?

新手问题: 使用 NestJS 和 TypeORM 时,已经创建了一个自定义存储库(它扩展了标准存储库),是否还需要单独的服务class?

目前,我只使用自定义存储库 class,它工作正常,但我不确定这是否正确,可能有一些副作用。

顺便说一句,在另一个项目中我没有自定义回购,只有一个服务被注入了两个标准回购,这也很好用。

此致,
萨格罗伯特

我认为这取决于您想要在 typeORM 和最“前台”代码(典型嵌套应用程序中的控制器)之间添加多少层。

我自己解释一下:

如果需要,您通常可以将内置的 typeORM 存储库直接注入到您的控制器中:

import {Controller, Get} from '@nestjs/common';
import {InjectRepository} from '@nestjs/typeorm';
import {Repository} from 'typeorm';
import {User} from './entities/User.entity';

@Controller()
export class AppController {
    constructor(
        @InjectRepository(User)
        private readonly userRepository: Repository<User>,
    ) {
    }

    @Get()
    async root(): Promise<User> {
        return await this.userRepository.find(1);
    }
}

因此,这将是如何检索 ID = 1 的用户的较少层次实现。

现在,NEST 的文档建议抽象这个存储库并将其注入到服务中,而不是直接注入到控制器中。这允许您减少控制器和 TypeORM 之间的绑定。相反,具有此绑定的是您的服务。如果您有许多使用此存储库的控制器,并且您决定要更改 TypeORM 并使用新的花式 ORM,则必须更改每个控制器。

现在,如果您只是将存储库注入到您的服务中,并将此服务用于所有控制器,您只需更改服务的实现,所有控制器都将保持不变。

其次,假设您想测试您的应用程序。你将面临同样的问题。如果没有 SQL 连接,你怎么能 运行 你的测试呢?我想您的单元测试不是为了测试 TypeORM 行为而创建的,而是为了测试您的代码行为而编写的。

模拟注入到服务中的存储库比模拟注入到控制器中的所有存储库要容易得多。

所以为了总结这个答案,我认为这个问题应该结束,因为它主要是基于意见的。但是 IMO,梦想中的架构如下:

  • 创建一个扩展 TypeORM 存储库的自定义存储库。
  • 在自定义存储库中,添加使用查询生成器的方法。
  • 将此自定义存储库注入您的服务
  • 将服务注入您的控制器。

永远不要在控制器中使用查询构建器,因为它很难模拟。

我希望这能回答您的问题:不需要服务 class。但它会帮助您保持代码整洁。