【前端学习】 NestJS 之 提供器 (Provider)

提供器 (Provider)

提供器 (provider) 是 Nest 中的一个基本概念。许多基本的 Nest 类可以被视为提供器 - 服务、存储库、工厂、助手等等。而提供器的主要思想是它可以作为依赖注入;这也意味着对象之间可以创建各种关系。

在控制器章节中,我们创建了一个DogsController类,然而 控制器应该处理 HTTP 请求并将更复杂的任务委托给提供器。提供程序是在module中声明为providers 的纯 JavaScript 类。

提一嘴:无论你记得与否,强烈建议你遵循SOLID 原则

*服务 (services)

让我们从搭建一个简单的 DogsService 开始吧。该服务将负责数据存储和检索,并设计为供 DogsController 使用。这说明什么?这说明把DogsService被定义为提供器是 100% 没问题的~

首先,在dogs 文件夹目录下创建一个名为dogs.service.ts的文件:

注意: 你同样可以使用CLI 来创建,只需在终端执行nest g service dogs命令即可。

/* dogs.service.ts */
import { Injectable } from "@nestjs/common";
import { Dog } from "./interfaces/dog.interface";

@Injectable()
export class DogsService {
	private readonly dogs: Dog[] = [];

	create(dog: Dog) {
		this.dogs.push(dog);
	}

	findAll(): Dog[] {
		return this.dogs;
	}
}

但是看到第二行就不难从代码中发现,引入的Dog 是什么?这里的Dog 便是我们的Dog 接口( interface )。它看起来可能是这样的:

/* src/dogs/interfaces/dog.interface.ts */
export interface Dog {
	name: string;
	age: number;
	bark: string;
}

不难看出,我们的DogsService是一个具有一个属性和两个方法的基本类。唯一的新特性是它使用了@Injectable()装饰器。

那么我们有了一个可以检索狗的服务类了,就在DogsController中使用它吧:

注意:在这里我们修改了之前dogs.controller.ts的代码:

/* dogs.controller.ts */
// ...
import { Dog } from "./interfaces/dog.interface";
import { DogsService } from "./dogs.service";

@Controller('dogs')
export class DogsController {
    constructor(private dogsService: DogsService) {}

    @Post()
    async create(@Body() createDogDto: CreateDogDto) {
        this.dogsService.create(createDogDto);
    }

    @Get()
    async findAll(): Promise<Dog[]> {
        return this.dogsService.findAll();
    }

    // ...
}

对于上方新增修改的代码:

  • constructor(...) {}DogsService通过类的构造函数注入

  • (private dogsService: DogsService):此private语法的使用允许我们立即在同一位置声明和初始化catsService成员;

  • 后续的代码块修改:简单来说,就是我们在DogsService内定义了两个方法,分别在POST 和GET 请求里调用使用它们就可以了。

  • 其中对于createDogDto: 该请求负载在之前并没有发挥作用,如今它的作用来了:它可以携带着对应的请求体去添加新增数据,这也是为什么create-dog.dto.ts内的类属性与我们的dog.interface.ts内的属性相同的原因。

目前对于我们学到的注入方式,可以将其称之为:基于构造函数的注入

提供器的注册 (registration)

现在我们已经有了一个提供器了(DogsService) ,并且该提供器也有一个消费者(DogsController) ,接下来要做的就是向Nest 注册该服务,以便它可以执行注入。我们需要做的就是:编辑模块文件(app.module.ts) 并将服务添加到Module()装饰器的providers数组内。

如下:

/* app.module.ts */
// ...
import { DogsService } from './dogs/dogs.service';

@Module({
  imports: [],
  controllers: [AppController, DogsController],
  // 在本注释的下方的providers 数组内添加DogsService
  providers: [AppService, DogsService],
})
export class AppModule {}

现在,Nest 就可以解析DogsController类的依赖了。

此时的目录结构可以给大家展示一下:

src 的目录结构

然后当我们再次将项目跑起来 (或者你在dev 环境下运行,一直在监视文件变化则无需再次跑起来 )时,来看看对应的效果:

添加前的GET 请求结果

这时候你会发现返回的是一个空数组,因为此时我们没有任何的数据存在里面;那么我们用ApiFox 来往里面存一两条数据试试:

POST 请求添加数据

由于我们的代码中只是执行了DogsServicecreate() 方法,即 将对应的数据存在了私有的dogs数组中,在DogsController类内也没有返回值,故不会返回任何内容。

在这里还要提一嘴的是,POST 请求的payload (请求体 & 请求负载) 在ApiFox 中是放在Body 里的,和我们使用的 @Body()装饰器 是不是一模一样呢~ 请求体内的参数格式,大家按照我这里的填写就ok~

然后我们再发送一次GET 请求试试:

添加后的GET 请求结果

是不是很有意思?仿佛自己像一个后端程序员一样写了一个接口出来?你仿佛的没错,这就是Nest !恭喜你到此为止,已经掌握了controllerprovider 的基本使用了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值