koa2 是基于 NodeJS 下一代 Web 开发框架。但是,Koa2 并没法像 Java 的 SpringBoot 框架那般开箱即用。Koa2 如果不通过二次封装,真的很难直接作为 Web 开发框架开发具体的业务。 Koa 最主要的核心就是 应用上下文 和 中间件。因此,Koa2 如果想要像 SpringBoot 可以给开发者开箱即用,显然是不可能。而且,Koa2 在以前版本是不支持 ESModule 的,即无法使用 import 导入,只能使用 require。不过目前 Koa 依赖 node v7.6.0+ 或 ES2015 及更高版本和 async 方法支持,可以实现 ESModule 方式的使用。 随着 Typescript 的普及,作为 NodeJS 的开发框架当然使用 TS 类型才能降低维护成本。对此,本人在 Koa2 + Typescript 的基础集成了一个 Web 开发框架 -- koa-web。大家要是觉得koa-web不错,可以给个star,谢谢!
前言
koa2 是基于 NodeJS 下一代 Web 开发框架。但是,Koa2 并没法像 Java 的 SpringBoot 框架那般开箱即用。Koa2 如果不通过二次封装,真的很难直接作为 Web 开发框架开发具体的业务。 Koa 最主要的核心就是 应用上下文 和 中间件。因此,Koa2 如果想要像 SpringBoot 可以给开发者开箱即用,显然是不可能。而且,Koa2 在以前版本是不支持 ESModule 的,即无法使用 import 导入,只能使用 require。不过目前 Koa 依赖 node v7.6.0+ 或 ES2015 及更高版本和 async 方法支持。 随着 Typescript 的普及,作为 NodeJS 的开发框架当然使用 TS 类型才能降低维护成本。对此,本人在 Koa2 + Typescript 的基础集成了一个 Web 开发框架 -- koa-web。大家要是觉得koa-web不错,可以给个star,谢谢!
koa-web Github 地址:https://github.com/zeffon/koa-web
koa-web npm 地址:https://www.npmjs.com/package/create-koa-web
正文
Koa-web
- 💡 TypeScript: 支持 TypeScript
- 🎨 prettier:prettier 规范代码格式
- 🚀 全局异常:全局异常统一处理
- ✈️ 数据校验:实用且高效的数据校验方式
- 🍀 Database:支持 Sequelize 连接
- 🔥 Redis:支持 Redis 数据库连接
- ⚡ Cache:支持 本地缓存
- ✍️ Auth:通用 JWT 授权
- 📖 日志:记录 SQL 日志和错误日志
- ✅ 单元测试:支持单元测试
- 📝 API 文档:API 文档测试
运行
如果你想要使用 koa-web 来作为 web 开发框架,是不需要下载 github 代码,直接使用 npm 命令快速搭建脚手架
$ npm create koa-web@latest
# 或者指定项目名称
$ npm create koa-web@latest koa-web-project
安装完毕,即可运行
# 1. 打开安装的项目
$ cd koa-web-project
# 2. 安装依赖
$ npm install
# 3. 运行项目
$ npm run start
# 4. 打开在线文档
# please open in: http://127.0.0.1:3000/koa-web/v1/doc.html
使用
一个 web 开发框架最核心、最基础的无非就是从异常处理和数据校验这两个模块开始。
全局异常
借助 Koa2 中间件的特性实现了全局异常捕获及处理。 Koa-web 中,异常分为两种:
- 已知异常
- 未知异常
已知异常(HTTP 异常) 又分为:
- 参数异常 ParameterException
- 未授权异常 UnAuthenticatedException
- 禁止访问异常 ForbiddenException
- 404 异常 NotFoundException
- 服务不可用异常 ServerErrorException
- 数据操作 GET、POST、PUT、DELETE(Koa-web 对数据操作成功也算是一种异常)
通过在 exception-code
定义相对应错误码和错误提示,抛出去异常就可以统一格式了。
在系统初始化阶段,UnifyResponse
统一返回格式 赋值给 global.UnifyResponse
,之后在编写业务代码便可以使用 global.UnifyResponse
根据确定的异常分类返回对应的异常信息。
未知异常 一般是未发现的异常提示,目前可以通过记录日志的方式记录该异常信息。
数据校验
数据校验有两种校验层次,一种是基于 koa-swagger-decorator 进行简单参数传递的校验,另一种是基于 validator 封装的复杂参数校验 LinValidator(来自 7 七月老师)。 koa-swagger-decorator 中的参数校验也是基于 validator 上。而 Koa-web 为什么有了 自己封装的参数校验器,还要使用 koa-swagger-decorator 呢?使用 koa-swagger-decorator 是想让 Koa-web 可以 在线 API 文档 调试,而 koa-swagger-decorator 在参数传递上有自己一套校验规则,权衡一二后,将简单规则的校验放在 koa-swagger-decorator ,而 LinValidator 用来校验复杂参数。
- koa-swagger-decorator 的详细规则使用可以查看其官方 Github 地址。
- LinValidator 的使用
Koa-web 相关模块的校验器是统一放置在 src/app/api/valid
目录下,比如:
export class RegisterValidator extends LinValidator {
private email;
private nickname;
private password1;
private password2;
private remark;
constructor() {
super();
this.email = [
new Rule("isLength", "Min 12 characters, max 32 characters", {
min: 6,
max: 32,
}),
new Rule("isEmail", "Please enter email format"),
];
this.nickname = [
new Rule("isLength", "Nickname does not match the length", {
min: 4,
max: 32,
}),
];
this.password1 = [
new Rule("isLength", "Password has min 6 characters, max 32 characters", {
min: 6,
max: 32,
}),
new Rule(
"matches",
"Password does not meet specifications",
"^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]"
),
];
this.password2 = this.password1;
this.remark = [
new Rule("isOptional"), // 可选,不校验
];
}
validatePassword(vals: any) {
const password1 = vals.body.password1;
const password2 = vals.body.password2;
if (password1 !== password2) {
throw new Error("Both passwords must be the same");
}
}
}
Auth 认证
core 目录下 auth 模块是认证机制。Koa-web 的授权机制是基于 jsonwebtoken 来 颁发 和 校验 Token 令牌的。Koa-web 全局拦截所有请求,除了在 unlessPaths 中路由,其它所有的请求都需要在请求头上携带 authorization 参数后才能正常访问,不然只能返回 401 请求。 unlessPaths 中路由数组就是过滤 url 路由。unlessPaths 支持字符串精准的路由和正则匹配规则的路由方式(推荐使用正则方式)。
let unlessPaths = [
/^\/koa-web\/v1\/json\.html[\/#\?]?$/i,
/^\/koa-web\/v1\/doc\.html[\/#\?]?$/i,
/^\/koa-web\/v1\/user\/login[\/#\?]?$/i,
/^\/koa-web\/v1\/user\/register[\/#\?]?$/i
]
# 或者
let unlessPaths = [
'/koa-web/v1/json.html',
'/koa-web/v1/doc.html',
'/koa-web/v1/user/login',
'/koa-web/v1/user/register'
]
数据库连接
数据库是 sequelize 进行连接的,采用 MySQL 引擎。而对数据库操作采用 sequelize 的模型。可以参考 Koa-web 中的 user 模块进行模型设计,配置上正确的数据库地址便可以生成对应的表结构。配置文件在 config 目录下,分有三种运行环境文件,选择当前运行环境的文件进行配置 DATABASE 相关参数配置。
在 src/app/api/model
下编写对应的模型,并且需要在 index.ts
进行导出,会在 src/core/database/init.ts
检测到定义的模型,进行数据库表创建。
Redis 数据库
在 config 配置下,REDIS.ENABLED 是否开启 Redis 服务,填写正确的 redis 的 host、port、password 连接 Redis 客户端。提供三个方法操作数据的存储、获取、删除,更多方法可以进行扩展。
本地缓存
本地缓存是存储在 NodeJS 进程中,会随着进程的重启而被清楚缓存数据。可以存储一些不重要的数据。
API 文档
API 文档 是采用 koa-swagger-decorator 实现的。可以通过装饰器的方式,更加简洁将 api 接口编码出来。并且借助 koa-swagger-decorator 实现简单的参数校验。在 API 文档上可以更加方便地、直观地进行调试接口。