当前位置:网站首页>Nest.js框架项目初始化实践
Nest.js框架项目初始化实践
2022-08-02 03:34:00 【deft_】
Nest.js框架项目初始化实践
实现背景:
Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架。它利用 JavaScript 的渐进增强的能力,使用并完全支持 TypeScript (仍然允许开发者使用纯 JavaScript 进行开发),并结合了 OOP (面向对象编程)、FP (函数式编程)和 FRP (函数响应式编程)。
Nest.js官方文档
Nest.js是一个使用TS开发的框架,使用了很多java相关的思想,很适合前端与JS工程师了解,此篇文章是我的一次项目初始化实践。
该项目数据库使用了 MongoDB、项目依赖库管理由 yarn 构建,同时集成了 Swagger 接口文档
项目实现:
init:
$ npm i -g @nestjs/cli
$ nest new nest-cil # your project-name
1、package manager 我们选择 yarn 回车即可
2、稍等片刻即可创建成功,此时的项目结构如下:
Install Dependencies:
$ yarn add mongoose @nestjs/mongoose # mongoDB 操作库 ( mongo版 sequelize )
$ yarn add @nestjs/swagger swagger-ui-express fastify-swagger # swagger 相关依赖
$ yarn add class-validator # 数据校验依赖库
Config Project & Schema
1、配置logger模块:
我们在根目录新建loggor文件夹,新建以下三个文件:
// logger.service.ts
import {
Injectable, Scope, Logger } from '@nestjs/common';
@Injectable({
scope: Scope.TRANSIENT })
export class LoggerService extends Logger {
}
// logger.module.ts
import {
Module } from '@nestjs/common';
import {
LoggerService } from './logger.service';
@Module({
imports: [],
controllers: [],
providers: [LoggerService],
exports: [LoggerService],
})
export class LoggerModule {
}
// logger.service.spec.ts 这文件没那么重要
import {
Test, TestingModule } from '@nestjs/testing';
import {
LoggerService } from './logger.service';
describe('LoggerService', () => {
let service: LoggerService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [LoggerService],
}).compile();
service = module.get<LoggerService>(LoggerService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
2、添加Schema相关模块 (数据库操作模块):
新建一个文件夹(文件名为表名),创建以下文件
1、DTO-数据传输对象
// deviceType.dto.ts 数据传输对象
import {
IsNotEmpty, MinLength, MaxLength } from 'class-validator'; // 校验
import {
ApiProperty } from '@nestjs/swagger';
export class DeviceTypeDto {
@ApiProperty({
example: 1, description: '设备编号' })
@IsNotEmpty({
message: '设备编号不能为空' })
readonly deviceTypeNo: number;
@ApiProperty({
example: 'Nick设备', description: '设备名' })
@IsNotEmpty({
message: '设备名不能为空' })
readonly name: string;
@ApiProperty({
example: '这是备注', description: '备注' })
readonly remarks: string;
}
2、Interface-数据范式
// deviceType.interface.ts 数据范式
export interface DeviceType {
id?: string;
deviceTypeNo?: string;
name?: string;
remarks?: string;
}
3、schema-数据表结构
// deviceType.schema.ts 数据表结构
import {
Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import {
Document } from 'mongoose';
@Schema()
export class DeviceType extends Document {
@Prop({
type: Number, required: true })
deviceTypeNo: string;
@Prop({
type: String, required: true })
name: string;
@Prop({
type: String, required: false })
remarks: string;
}
export const DeviceTypeSchema = SchemaFactory.createForClass(DeviceType);
4、service-方法函数
// deviceType.service.ts 数据表结构
import {
Injectable } from '@nestjs/common';
import {
DeviceType } from './schemas/deviceType.schema';
import {
Model } from 'mongoose';
import {
InjectModel } from '@nestjs/mongoose';
import {
DeviceTypeDto } from './dto/deviceType.dto';
@Injectable()
export class DeviceTypeService {
constructor(@InjectModel('DeviceType') private readonly deviceTypeModel: Model<DeviceType>) {
}
async findAll(): Promise<DeviceType[]> {
return this.deviceTypeModel.find().exec();
}
async findById(id: string): Promise<DeviceType> {
return id.match(/^[0-9a-fA-F]{24}$/)
? await this.deviceTypeModel.findOne({
_id: id })
: null;
}
async create(item: DeviceTypeDto) {
const newItem = new this.deviceTypeModel(item);
return newItem.save();
}
async delete(id: string): Promise<DeviceType> {
return this.deviceTypeModel.findByIdAndRemove(id);
}
async update(id: string, deviceType: DeviceTypeDto): Promise<DeviceType> {
return await this.deviceTypeModel.findByIdAndUpdate(id, deviceType, {
new: true});
}
}
5、controller-接口路由控制器
// deviceType.controller.ts 数据表结构
import {
Body, Controller, Delete, Get, Param, Post, Put, UsePipes } from '@nestjs/common';
import {
ApiOperation,
ApiTags,
ApiQuery,
ApiBody,
ApiResponse,
} from '@nestjs/swagger';
import {
DeviceTypeDto } from './dto/deviceType.dto';
import {
DeviceTypeService } from './deviceType.service';
import {
DeviceType } from './interfaces/deviceType.interface';
import {
LoggerService } from 'src/logger/logger.service';
import {
ValidationPipe } from'../pipe/validation.pipe';
@Controller('deviceType')
@ApiTags('deviceType')
export class DeviceTypeController {
constructor(
private readonly deviceTypeService: DeviceTypeService,
private logger: LoggerService,
) {
}
@Get('/queryAll')
@ApiOperation({
summary: '查找所有设备类型' })
async findAll(): Promise<DeviceType[]> {
this.logger.debug('Get All Items Endpoint');
return this.deviceTypeService.findAll();
}
@Get('queryOne/:id')
@ApiOperation({
summary: '根据ID查找设备类型' })
// @ApiQuery({ name: 'limit', required: true })
async findById(@Param() param): Promise<DeviceType> {
return this.deviceTypeService.findById(param.id);
}
@UsePipes(new ValidationPipe()) // 使用管道验证
@Post('/create')
@ApiOperation({
summary: '创建设备类型', description: '创建设备类型' })
async create(@Body() itemDTO: DeviceTypeDto): Promise<DeviceType> {
return this.deviceTypeService.create(itemDTO);
}
@Put('update/:_id')
@ApiOperation({
summary: '更新设备类型' })
@ApiBody({
type: DeviceTypeDto, description: '参数可选' })
@ApiResponse({
status: 200,
description: '成功返回200,失败返回400',
type: DeviceTypeDto,
})
async update(@Param() param, @Body() DeviceTypeDto: DeviceTypeDto): Promise<DeviceType> {
return this.deviceTypeService.update(param.id, DeviceTypeDto);
}
@Delete('delete/:id')
@ApiOperation({
summary: '删除设备类型' })
async delete(@Param() param): Promise<DeviceType> {
return this.deviceTypeService.delete(param.id);
}
}
5、module-模块构造器
// deviceType.module.ts 数据表结构
import {
Module } from '@nestjs/common';
import {
MongooseModule } from '@nestjs/mongoose';
import {
LoggerModule } from 'src/logger/logger.module';
import {
LoggerService } from 'src/logger/logger.service';
import {
DeviceTypeController } from './deviceType.controller';
import {
DeviceTypeService } from './deviceType.service';
import {
DeviceTypeSchema } from './schemas/deviceType.schema';
@Module({
imports: [
MongooseModule.forFeature([{
name: 'DeviceType', schema: DeviceTypeSchema }]),
LoggerModule,
],
controllers: [DeviceTypeController],
providers: [DeviceTypeService, LoggerService],
})
export class DeviceTypeModule {
}
3、数据库Config & env:
// config/configuration.ts 数据表结构
export default () => ({
// port: 27017,
port: 3000,
database: {
uri: `mongodb://${
process.env.DB_HOST_D}:${
process.env.DB_PORT_D}/${
process.env.DB_NAME_D}`,
// uri: `${process.env.DB_NAME_D}`,
},
});
// .env 项目根目录创建
NODE_ENV=development
DB_HOST_D=127.0.0.1 //数据库地址
DB_NAME_D=testMongo //数据库名
DB_PORT_D=27017 // 端口
3、app.module & main:
// app.module.ts 数据表结构
import {
LoggerModule } from './logger/logger.module';
import {
DeviceTypeModule } from './deviceType/deviceType.module';
import {
Module } from '@nestjs/common';
import {
MongooseModule } from '@nestjs/mongoose';
import {
ConfigModule, ConfigService } from '@nestjs/config';
import configuration from './config/configuration';
@Module({
imports: [
LoggerModule
DeviceTypeModule,
ConfigModule.forRoot({
isGlobal: true,
load: [configuration],
}),
MongooseModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
uri: `${
configService.get('database.uri')}`,
}),
inject: [ConfigService],
}),
],
controllers: [],
providers: [],
})
export class AppModule {
}
// main.ts 项目根目录创建
import {
ConfigService } from '@nestjs/config';
import {
NestFactory } from '@nestjs/core';
import {
AppModule } from './app.module';
import {
DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const configService: ConfigService = app.get(ConfigService);
// swagger 相关配置,具体在controller中配置
const swaggerOptions = new DocumentBuilder()
.setTitle('ez-DeviceLib-文档') // 文档标题
.setDescription('DeviceLib-api-说明') // 文档描述
.setVersion('1.0') // 文档版本
.addBasicAuth() // 鉴权相关
.build(); // 创建
//创建swagger
const document = SwaggerModule.createDocument(app, swaggerOptions);
//启动swagger
SwaggerModule.setup('doc', app, document);
await app.listen(configService.get('port'));
}
bootstrap();
Start Databases:
1、下载mongoDB并配置:
Win:https://www.mongodb.com/download-center/community
Linux:https://www.runoob.com/mongodb/mongodb-linux-install.html
Mac:https://www.mongodb.com/download-center#community
2、配置完成后启动:
$ sudo mongod --dbpath=/Users/ezpro/data
$ mongo
以下结果即为启动成功:
Start Project:
$ npm start
Swagger:
本地浏览器打开 http://localhost:(env-port)/doc/
项目Github地址:
nest-cil:https://github.com/hyxONick/nest-cil
总结:
TS、Nest.js相较于传统JS与Koa等框架相比规范性有了很大的提升,加上Nest的OOP、FP和FRP等类java思想,让其更加严谨与规范,更像是一门规范的后台语言。
边栏推荐
猜你喜欢
【Connect the heart rate sensor to Arduino to read the heart rate data】
哈希表解题方法
onvif/rtsp转gb28181协议,无缝对接国标平台
【nRF24L01 connects with Arduino to realize wireless communication】
开源日志库 [log4c] 使用
剑指Offer 34.二叉树中和为某一值的路径 dfs+回溯
2020 - AAAI - 图像修复 Image Inpainting论文导读 -《Region Normalization for Image Inpainting》
bluez5.50蓝牙文件传输
rosdep update failure solution (pro-test effective)
STM32 CAN 介绍以及相关配置
随机推荐
IDEA2021.2安装与配置(持续更新)
发布全新的配置格式 - AT
Flame sensor connected with Arduino
[Database] Four characteristics of transaction
uniCloud use
2020 - AAAI - Image Inpainting论文导读《Learning to Incorporate Structure Knowledge for Image Inpainting》
谷粒商城10——搜索、商品详情、异步编排
学习(四):显示FPS,和自定义显示调试
JS从扁平array转tree
v-model修饰符
进程(番外):自定义shell命令行解释器
引擎开发日志:场景编辑器开发难点
只出现一次的字符
“520” 如何正确地用代码向 ta 表白?
【操作系统】线程安全保护机制
电脑基本知识
LT8918L LVDS转MIPI芯片技术支持资料
本地数据库 sqlite3 编译和使用
【LeetCode】合并
最长公共子串