常用脚手架命令
- 创建项目
nest new [project]
- 创建模块
nest g mo [name] --no-spec
- 创建控制器
nest g co [name] --no-spec
- 创建服务
nest g s [name]
全称 | 别名 |
---|---|
name | alias |
application | application |
class | cl |
configuration | config |
controller | co |
decorator | d |
fitter | f |
gateway | ga |
guard | gu |
interceptor | in |
interface | interface |
middleware | mi |
module | mo |
pipe | pi |
provider | pr |
resolve | r |
service | s |
library | lib |
sub-app | app |
处理流程
发送http请求,根据路由匹配对应的控制器
控制器去访问服务层
服务层对数据进行操作
模块文件解析
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [], // 注册的其它模块
controllers: [AppController], //该模块提供的控制器
providers: [AppService], // 该模块提供的服务
exports: [], // 别的模块要使用该模块中的某几个方法,就要在这里对外暴漏
})
export class AppModule {}
controllers
文件解析
写路由,注入路由对应的服务,将注入的服务执行
// 路由地址
@Controller()
export class AppController {
// 依赖服务注入
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
// 可以使用其它模块的服务
return this.appService.getHello();
}
}
service
层
主要是做数据交互
@Injectable()
export class AppService {
getHello(): string {
return 'Hello hogsen';
}
}
IOC控制反转与DI 依赖注入
假设我有两个模块,moduleA
与moduleB
,现在我要在模块A中使用模块B的服务我应该怎么写。
第一种写法
我直接在模块A中调用模块B,这样写是可行的对吧,但是会有一个很严重的问题,A,B模块具有强耦合关系,
模块B对于模块A具用很强的副作用。模块A不纯,它有很强的副作用。
那么如何去减少副作用,让代码更健壮
第二种写法
跟发布订阅模式差不多,模块之间并没有什么依赖关系,IOC容器负责收集依赖,以及对外提供服务。模块对外提供一个接收服务的接口。尽量确保模块是纯的没有副作用的。在前端中属于组件通信的一种方式。
class Container {
moudle;
constructor() {
this.moudle = {};
}
// 收集依赖
service(key: string, moudle) {
this.moudle[key] = moudle;
}
// 对外提供服务
provide(key: string) {
return this.moudle[key];
}
}
class Teacher {
name;
constructor(name) {
this.name = name;
}
static teach(stu) {
console.log(`教${stu}读书`);
}
}
class Student {
name;
constructor(name) {
this.name = name;
}
inject(fn) {
fn(this.name);
}
}
const container = new Container();
// 收集依赖
container.service('te', Teacher);
container.service('stu', Student);
const hogsen = new Student('hogsen');
// 注入容器提供的服务
hogsen.inject(container.provide('te').teach);
装饰器模式
在nest中大量使用了装饰器,所以我们必须要理解装饰器模式
在typescript
中装饰器分为
- 类装饰器
ClassDecorator
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
接收一个参数target
表示构造函数 - 属性装饰器
PropertyDecorator
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
它接收两个参数,target
是原型对象,propertyKey
就是该属性 - 方法装饰器
MethodDecorator
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
接收原型对象,该方法名,属性描述符对象 - 参数装饰器
ParameterDecorator
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => void;
接收原型对象,该方法名,参数位置