初始化项目
首先创建个 nest 项目:
nest new server
进入src/main.js
设置前缀
// 设置前缀
app.setGlobalPrefix('api');
设置版本
// 设置版本
app.enableVersioning({
type: VersioningType.URI,
});
设置跨域
// 设置跨域
app.enableCors();
设置swagger
后端写完接口,都会提供一份接口文档给前端。
这节我们就来做下这件事情,通过 swagger 生成接口文档。
安装 swagger 的包:
npm install --save @nestjs/swagger
设置swagger
const options = new DocumentBuilder()
.setTitle('博客api')
.setDescription('博客api')
.setVersion('1.0')
.addTag('博客api')
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('api-docs', app, document);
我们的博客系统还需要用到mysql,redis和邮件服务
配置mysql
安装 typeorm 相关的包:
npm install --save **@nestjs**/typeorm typeorm mysql2
在 AppModule 引入 TypeOrmModule:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
TypeOrmModule.forRoot({
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "root",
database: "blog",
synchronize: true,
logging: true,
entities: [],
poolSize: 10,
connectorPackage: 'mysql2',
extra: {
authPlugin: 'sha256_password',
}
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
在MySQL中创建blog数据库
配置redis
安装redis的包
npm install --save redis
封装redis模块
nest g module redis
nest g service redis
连接redis
import { Global, Module } from '@nestjs/common';
import { RedisService } from './redis.service';
import { createClient } from 'redis';
@Global()
@Module({
providers: [
RedisService,
{
provide: 'REDIS_CLIENT',
async useFactory() {
const client = createClient({
socket: {
host: 'localhost',
port: 6379
},
database: 1
});
await client.connect();
return client;
}
}
],
exports: [RedisService]
})
export class RedisModule {}
这里用 @Global() 把它声明为全局模块,这样只需要在 AppModule 里引入,别的模块不用引入也可以注入 RedisService 了。
database 指定为 1,因为我们之前都是用的默认的 0
redis 的 database 就是一个命名空间的概念:
编辑RedisService
import { Inject, Injectable } from '@nestjs/common';
import { RedisClientType } from 'redis';
@Injectable()
export class RedisService {
@Inject('REDIS_CLIENT')
private redisClient: RedisClientType;
async get(key: string) {
return await this.redisClient.get(key);
}
async set(key: string, value: string | number, ttl?: number) {
await this.redisClient.set(key, value);
if(ttl) {
await this.redisClient.expire(key, ttl);
}
}
}
注入 redisClient,实现 get、set 方法,set 方法支持指定过期时间。
配置邮件
nest g resource email
安装发送邮件用的包:
npm install nodemailer --save
在 EmailService 里实现 sendMail 方法
import { Injectable } from '@nestjs/common';
import { createTransport, Transporter} from 'nodemailer';
@Injectable()
export class EmailService {
transporter: Transporter
constructor() {
this.transporter = createTransport({
host: "smtp.qq.com",
port: 587,
secure: false,
auth: {
user: '你的邮箱地址',
pass: '你的授权码'
},
});
}
async sendMail({ to, subject, html }) {
await this.transporter.sendMail({
from: {
name: '会议室预定系统',
address: '你的邮箱地址'
},
to,
subject,
html
});
}
}
把邮箱地址和授权码改成你自己的。
在EmailModule 中
把 EmailModule 声明为全局的,并且导出 EmailService
配置抽离
我们把配置抽离一下,现在的 mysql、redis、nodemailer 等配置都直接写在代码里,不好维护。
安装 config 的包:
npm install --save @nestjs/config
在 AppModule 引入下:
设置为全局模块,指定 env 文件的位置。
为什么 .env 不放在根目录呢?
因为根目录下的配置文件不会自动复制到 dist 目录。
我们在 nest-cli.json 里加一下 assets 的配置:
asssets 是指定 build 时复制的文件,watchAssets 是在 assets 变动之后自动重新复制。
然后在 src 下添加一个 .env 文件:
然后在 RedisModule 里注入 ConfigService 来读取配置:
在 .env 里添加 redis、mysql、nodemailer 和 nest 服务的配置:
# redis 相关配置
redis_server_host=localhost
redis_server_port=6379
redis_server_db=1
# nodemailer 相关配置
nodemailer_host=smtp.qq.com
nodemailer_port=587
nodemailer_auth_user=你的邮箱
nodemailer_auth_pass=你的授权码
# mysql 相关配置
mysql_server_host=localhost
mysql_server_port=3306
mysql_server_username=root
mysql_server_password=root
mysql_server_database=blog
# nest 服务配置
nest_server_port=3000