前言:
随着互联网的快速发展,Web 开发已成为当今计算机领域中非常重要的一部分。
Node.js 的出现为前端开发者提供了一个全新的方向,使得他们可以同时涉足前端和后端开发。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,它使 JavaScript 有了在服务器端运行的能力,使得前端开发者可以使用已经熟悉的 JavaScript 语言来开发后端应用程序。
使用node开发后端服务框架有:express、koa、nestjs、fastify等等。
大厂企业级Nodejs的应用实践
一、express
官网网址:https://www.expressjs.com.cn/
express adj 快速的
安装:
shell
npm install express --save
优点:
- 使用简单,上手容易。
- 社区活跃,文档齐全。
- 提供了很多预定义的中间件和路由,使得开发者可以快速地搭建出一个 Web 应用程序。
- 已经经过了很长时间的实践,稳定性和可靠性较高。
缺点:
基于ES5的语法,要实现异步代码,只有一个方法:回调。如果异步嵌套层次过多,代码写起来就非常难看
实现异步
js
app.get('/', (req, res) => {
new Promise((resolve, reject) => {
resolve(A())
})
.then((r) => {
return B(r)
})
.then((r) => {
res.send({
name: r,
age: 18
})
})
})
function A() {
return 'A'
}
function B(name) {
return name + 'B'
}
错误处理
js
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
解析参数
shell
// get
app.get('/', (req, res) => {
console.log('req', req.query)
})
// post
// 前提:解析post数据需要用到body-parser
app.post('/test', (req, res) => {
console.log(req.body)
res.send(req.body)
})
连接数据库
https://blog.csdn.net/qq_43852612/article/details/131390670
二、koa
安装:
Koa 依赖 node v10.16.0 或 ES2015及更高版本和 async 方法支持。
shell
npm install koa
npm install koa-router // 路由
npm i -S koa-combine-routers // 合并路由
优点:
- 简洁、只需通过添加中间件对数据处理
- async/await
- 丰富的中间件
缺点:
- 相对于 Express,Koa 的学习曲线较陡峭,需要开发者具备一定的 JavaScript 基础和异步编程经验。
- 由于 Koa 是一个相对较新的框架,因此社区和文档相对较少,可能会给开发者带来一些不便。
错误处理
js
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.status = err.statusCode || err.status || 500;
ctx.body = {
message: err.message
};
}
});
连接数据库
https://blog.csdn.net/weixin_41897680/article/details/130916005
实现异步
js
router.get('/', async (ctx, next) => {
const a = await A()
const b = await B()
ctx.response.body = a + b
})
function A() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('A')
}, 2000)
})
}
function B() {
return 'B'
}
三、nest
介绍:
Nest(NestJS)是一个用于构建高效、可扩展 Node.js 服务器端应用程序的框架。它使用渐进式的JavaScript,完全支持并构建于 TypeScript 上(同时仍然允许开发者使用纯JavaScript进行编码),结合了面向对象编程(OOP)、函数式编程(FP)和函数响应式编程(FRP)的元素。
在内部,Nest使用强大的HTTP服务器框架,如 Express(默认)并且可以选择配置为使用 Fastify!
Nest在这些常见的Node.js框架(Express/Fastify)之上提供了一层抽象,同时也直接向开发者暴露了它们的API。这使得开发者可以自由使用众多为底层平台提供的第三方模块。
原理
尽管存在大量出色的库、助手和工具供Node(以及服务器端JavaScript)使用,但没有一个能有效地解决主要问题------架构
Nest提供了一个开箱即用的应用程序架构,允许开发者和团队创建高度可测试、可扩展、松耦合且易于维护的应用程序。
官方网址:https://nestjs.com/ (英文 )
nestjs中文网:https://nest.nodejs.cn/
第三方nestjs文档:http://nestjs.inode.club/
安装:
shell
npm i -g @nestjs/cli // 安装nest cli
nest new project-name // 初始化项目
目录介绍
文件 | 解释 |
---|---|
app.controller.ts | 一个具有单一路由的基本控制器. |
app.controller.spec.ts | 控制器的单元测试. |
app.module.ts | 应用程序的根模块. |
app.service.ts | 一个基本的服务,拥有一个单一的方法. |
main.ts | 应用程序的入口文件将使用核心函数 NestFactory 来创建一个 Nest 应用程序实例. |
优点
-
TypeScript 支持:NestJS 的一个主要优势是它对 TypeScript 的一流支持。TypeScript 提供了强类型、接口和装饰器,这些特性有助于提高代码质量和可维护性。
-
模块化结构:NestJS 鼓励使用模块化架构,这有助于组织和分离关注点,使代码更易于管理和扩展。
-
依赖注入(DI):NestJS 实现了 Angular 风格的依赖注入系统,这使得代码更加干净、可测试,并易于重构。
-
内置应用程序架构:NestJS 提供了一个内置的应用程序架构,包括控制器、服务、中间件等,这有助于快速开发和维护大型应用程序。
-
微服务支持:NestJS 提供了一套简单的微服务选项,支持多种传输层策略,如 TCP、MQTT、RabbitMQ 等。
-
丰富的生态系统:NestJS 拥有一个活跃的社区和丰富的生态系统,提供了许多现成的模块和工具,以简化开发过程。
-
与其他库的良好集成:NestJS 可以很容易地与其他 JavaScript 库和模块集成,如 TypeORM、Mongoose 等。
缺点
-
学习曲线:对于不熟悉 TypeScript 或 Angular 的开发人员来说,NestJS 的学习曲线可能会比较陡峭。
-
性能开销:由于其抽象层和额外的功能,NestJS 可能会比一些更轻量级的 Node.js 框架有更多的性能开销。
-
相对较新:虽然 NestJS 社区正在迅速增长,但它相对于其他一些长期存在的 Node.js 框架(如 Express.js)来说还是较新的。这可能意味着某些情况下资源和支持有限。
-
过度工程化风险:NestJS 的严格架构和模式可能会导致过度工程化,特别是在小型项目或简单应用中。
-
可能的过度依赖框架:NestJS 的强大功能可能导致开发者过度依赖框架本身,从而限制了某些自定义和灵活性。
nest 常用命令
shell
nest --help
例子:创建user模块
shell
nest g res user
装饰器
装饰器是一种特殊的类型声明,他可以附加在类,方法,属性,参数上面
装饰器 | |
---|---|
@Request() | req |
@Response() | res |
@Next() | next |
@Session() | req.session |
@Param(key?: string) | req.params/req.params[key] |
@Body(key?: string) | req.body/req.body[key] |
@Query(key?: string) | req.query/req.query[key] |
@Headers(name?: string) | req.headers/req.headers[name] |
@HttpCode |
接口传参
get接口接参
@Request
js
@Get('/findall')
findAll(@Request() req: any) {
console.log(req.query); // get是query
return this.userService.findAll();
}
@Query
js
@Get('/findall')
findAll(@Query() req: any) {
console.log(req); // 直接读取传来的参数
return this.userService.findAll();
}
post接口接参
@Request
js
@Get('/findall')
findAll(@Request() req: any) {
console.log(req.body); // post是body
return this.userService.findAll();
}
js
@Post('/createuser')
create(@Body('age') req: any) {
console.log(req);
return this.userService.create();
}
动态参数
js
@Get('/findall/:id')
findAll(@Request() req: any) {
console.log(req.params.id);
return this.userService.findAll();
}
语法糖:
js
@Get('/findall/:id')
findAll(@Params() params: any) {
console.log(params.id);
return this.userService.findAll();
}
除此之外 我们还可以使用@Headers读取请求头的信息,使用@HttpCode控制返回的状态码
js
// header测试
@Get('/headertest')
@HttpCode(500)
headertest(@Headers() headers: any) {
console.log('headers', headers);
this.userService.findAll();
}
连接数据库
1. ORM框架(typeOrm)
官网:https://typeorm.bootcss.com/
typeOrm 是 TypeScript 中最成熟的对象关系映射器( ORM )。因为它是用 TypeScript 编写的,所以可以很好地与 Nest 框架集成,有了它就可以在nest中不使用sql操作数据库。
除了使用typeOrm还可以使用Prisma
安装依赖
shell
npm install --save @nestjs/typeorm typeorm mysql2
import { TypeOrmModule } from '@nestjs/typeorm';
TypeOrmModule.forRoot({
type: "mysql", //数据库类型
username: "root", //账号
password: "123456", //密码
host: "localhost", //host
port: 3306, //
database: "portal", //库名
entities: [__dirname + '/**/*.entity{.ts,.js}'], //实体文件
synchronize:true, //synchronize字段代表是否自动将实体类同步到数据库
retryDelay:500, //重试连接数据库间隔
retryAttempts:10,//重试连接数据库的次数
autoLoadEntities:true, //如果为true,将自动加载实体 forFeature()方法注册的每个实体都将自动添加到配置对象的实体数组中
}),
实体
实体是一个映射到数据库表的类。 你可以通过定义一个新类来创建一个实体,并用@Entity()来标记:
js
import {Entity,Column,PrimaryGeneratedColumn} from 'typeorm'
@Entity()
export class Test {
@PrimaryGeneratedColumn()
id:number
@Column()
name:string
@Column()
password:string
@Column()
age:number
}
主列
自动递增的主键
js
@PrimaryGeneratedColumn()
id:number
@PrimaryGeneratedColumn("uuid") // 自动递增的uuid
id:number
列类型
js
@Column({type:"varchar",length:200})
password: string
@Column({ type: "int"})
age: number
@CreateDateColumn({type:"timestamp"})
create_time:Date
列选项
js
@Column({
type:"varchar",
name:"ipaaa", //数据库表中的列名
nullable:true, //在数据库中使列NULL或NOT NULL。 默认情况下,列是nullable:false
comment:"注释",
select:true, //定义在进行查询时是否默认隐藏此列。 设置为false时,列数据不会显示标准查询。 默认情况下,列是select:true
default:"xxxx", //加数据库级列的DEFAULT值
primary:false, //将列标记为主要列。 使用方式和@ PrimaryColumn相同。
update:true, //指示"save"操作是否更新列值。如果为false,则只能在第一次插入对象时编写该值。 默认值为"true"
collation:"", //定义列排序规则。
})
ip:string
@InjectRepository(User) private readonly user: Repository?
在 NestJS 中,@InjectRepository(User) 是一个装饰器,用于依赖注入。这个特定的装饰器是 TypeORM 与 NestJS 集成的一部分,用于注入特定实体的仓库(在这个例子中是 User 实体)。它允许你在类中使用仓库模式,从而可以进行数据持久化操作,例如查询、插入、更新和删除。
数据的增删改查
请求拦截器