当前位置:网站首页>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思想,让其更加严谨与规范,更像是一门规范的后台语言。
边栏推荐
- Comparison between Boda Industrial Cloud and Alibaba Cloud
- openwrt RK3568_EVB移植
- 【MQ-3 Alcohol Detector and Arduino Detect Alcohol】
- 同时求最大值与最小值(看似简单却值得思考~)
- 2019 - ICCV - 图像修复 Image Inpainting 论文导读《StructureFlow: Image Inpainting via Structure-aware ~~》
- WebApp 在线编程成趋势:如何在 iPad、Matepad 上编程?
- Altium Designer Basics
- 发布全新的配置格式 - AT
- NSIS来自己设定快捷方式的图标
- Basic IO (below): soft and hard links and dynamic and static libraries
猜你喜欢

Host your own website with Vercel

The use and simulation of vector implementation:

Process (below): process control, termination, waiting, replacement

【详解】优先级队列的底层实现

【详解】线程池及其自定义线程池的实现

AD实战篇

字符串匹配(蛮力法+KMP)

Compatible with C51 and STM32 Keil5 installation method

Basic IO (below): soft and hard links and dynamic and static libraries

【nRF24L01 connects with Arduino to realize wireless communication】
随机推荐
剑指Offer 32.Ⅰ从上到下打印二叉树
Host your own website with Vercel
IDEA2021.2安装与配置(持续更新)
剑指Offer 36.二叉搜索树与双向链表 中序遍历
Altium Designer Basics
Basic IO (on): file management and descriptors
Process (below): process control, termination, waiting, replacement
工作过程中问题汇总
CCF刷题之旅--第一题
基础IO(下):软硬链接和动静态库
path 修补文件命令
改变文件的扩展名
MAC安装Mysql超详细完整教程
学习(三):事件的订阅与发布
判断回文
rosdep update failure solution (pro-test effective)
【详解】线程池及其自定义线程池的实现
vector的使用和模拟实现:
引擎开发日志:集成Bullet3物理引擎
最长连续不重复子序列 双指针