基于koa
的轻量级快速开发框架,包含 MVC 中的 M 和 C 两部分,适合于实现 API 服务和前后端彻底分离的应用。
内置基于 access_token 的访问鉴权机制,更容易实现 API 调用的负载分担。
内置通过连接池访问 MySQL 数据库,支持进行读写分离。内置 SQL 语句的封装,内置 escape 防止 sql 注入。目前 where 条件中,exists,and,or 形成的 sql 不会进行 escape 处理,需要在外部自行处理。select 中的 fields 和 table 未进行 escape 处理,不能够直接使用用户输入的内容作为字段名和表名。orderby 和 groupby 未做 escape 处理,不能够直接使用用户输入。
内置支持上传文件。
pnpm i
注意:tms_db,mongodb,mongoose,redis 这 4 个依赖包采用peerDependencies
,不会进行自动安装,如果需要使用可以手动安装。tms-db 的依赖包 mysql 和 better-sqlite3 采用peerDependencies
,不会进行自动安装,如果需要使用可以手动安装。
启动 Redis 和 MongoDb
docker-compose up -d
发送获得 token 的请求
curl -X POST -H "Content-type: application/json" "http://localhost:3009/auth/authenticate" -d '{"username":"admin","password":"admin"}'
发送调用 api 的请求
curl 'http://localhost:3009/api/tryGet?access_token=<前一步获得的access_token>&value=hello'
在项目的根目录下建立文件/config/app.js
,指定下列信息:
module.exports = {
port: 3000,
name: 'tms-koa-0',
router: {
auth: {
prefix: '', // 接口调用url的前缀
},
controllers: {
prefix: '', // 接口调用url的前缀,例如:/api
},
swagger: {
prefix: '/oas',
},
metrics: {
prefix: '/metrics', // 提供给prometheus的地址
},
},
auth: {
captcha: { code: 'a1z9' },
client: { accounts: [{ id: 1, username: 'user1', password: '123456' }] },
jwt: {
privateKey: 'tms-koa-secret',
expiresIn: 7200,
},
},
tmsTransaction: false,
body: {
// post 请求时对body大小的限制
jsonLimit: '1mb',
formLimit: '56kb',
textLimit: '56kb',
},
}
controllers
的prefix
在 url 中出现,例如:http://localhost:3001/api/tryGet?value=hello
,但是不在 controller 的路径中出现,例如:controllers/main.js 为与 url 对应的控制器。
参考:https://www.npmjs.com/package/koa-router
auth
部分是可选的,如果不配置或者disabled
设置为true
,就不启动鉴权机制。
支持jwt
和redis
两种token
认证机制,都支持用disabled
关闭,若同时设置,jwt
优先于redis
。
在项目的根目录下建立文件/config/redis.js
,指定下列 Redis 连接信息:
module.exports = {
disabled: false, // 可选项,不需要指定。主要用于开发调试阶段。
master: {
host: '127.0.0.1',
port: 6379,
password: '*****',
},
}
支持连接 redis 集群
module.exports = {
disabled: false, // 可选项,不需要指定。主要用于开发调试阶段。
master: {
redis: {
host: [
'192.168.43.127',
'192.168.43.127',
'192.168.43.127',
'192.168.43.127',
'192.168.43.127',
'192.168.43.127',
],
port: [
6381,
6382,
6383,
6384,
6385,
6386,
],
password = [
"********",
"********",
"********",
"********",
"********",
"********",
]
masterAuthPasswor = '********'
},
}
参考:https://www.npmjs.com/package/redis
在项目的根目录下建立文件/config/db.js
,指定下列 MySQL 或 Sqlite 数据库(可选)连接信息:
export default {
mysql: {
master: {
connectionLimit: 10,
host: '',
port: '',
user: '',
password: '',
database: '',
},
write: {
connectionLimit: 10,
host: '',
port: '',
user: '',
password: '',
database: '',
},
},
sqlite: {
path: '',
},
}
参考:https://www.npmjs.com/package/mysql
参考:https://github.com/JoshuaWise/better-sqlite3/blob/HEAD/docs/api.md
在项目的根目录下建立文件/config/mongodb.js
,指定下列 MongoDb 连接信息:
export default {
disabled: false, // 可选项,不需要指定。主要用于开发调试阶段。
master: {
host, // 如果要连接复制集,这里是复制集节点的主机地址数组(或者是逗号分隔的列表),否则是字符串
port: 27017, // 如果要连接复制集,这里是复制集节点的主机端口数组(或者是逗号分隔的列表),否则是整数
replicaSet: '', // 可选。复制集的名称
maxPoolSize, // 可选
authSource, // 可选
authMechanism, // 可选。例如:PLAIN
connectionOptions, // 可选
},
}
export default {
disabled: false, // 可选项,不需要指定。主要用于开发调试阶段。
master: {
connectionString, // 直接指定连接地址,不用指定host和port
replicaSet: '', // 可选。复制集的名称
maxPoolSize, // 可选
authSource, // 可选
authMechanism, // 可选。例如:PLAIN
connectionOptions, // 可选
},
}
注意:如果项目要使用 mongodb,需要在项目中安装 mongodb 包。
文件管理,例如:保存上传文件
export default {
local: {
rootDir: 'files' // 指定保存文件的根目录
accept: [
'text/plain',
'application/json',
'text/markdown',
'text/csv',
'application/pdf',
'image/.*',
'audio/.*',
'video/.*',
'application/vnd\\.openxmlformats-officedocument\\.spreadsheetml\\.sheet',
'application/vnd\\.ms-excel',
'application/vnd\\.openxmlformats-officedocument\\.wordprocessingml\\.document',
'application/msword',
'application/vnd\\.openxmlformats-officedocument\\.presentationml\\.presentation',
'application/vnd\\.ms-powerpoint',
], // 允许上传文件的类型的正则表达式
database: {
dialect: 'mongodb',
database:'upload',
file_table: 'files'
},
schemas: {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
title: 'Json-Doc-File',
description: 'tms-vue-finder file',
properties: {
comment: {
type: 'string',
minLength: 0,
maxLength: 80,
title: '说明1',
attrs: {
placeholder: '请输入说明',
title: '说明1'
}
}
}
}
}
}
tms-koa 支持保存上传文件的扩展信息。可以指定将信息保存在数据库中,例如:mongodb。指定的数据库需要在/config/mongodb.js 中存在。
支持向prometheus
提供监控数据。
在项目的根目录下建立文件/config/metrics.js
建立文件app.js
(可根据需要自行命名)
const { TmsKoa } = require('tms-koa')
const tmsKoa = new TmsKoa()
tmsKoa.startup()
可以在 startup 中添加其他中间件(middleware),例如:
控制器之前
tmsKoa.startup({ beforeController: [] })
控制器之后
tmsKoa.startup({ afterController: [] })
完成初始化,启动 http 和 https 端口之前
tmsKoa.startup({ afterInit: function (context) {} })
建立 controllers 目录放置 API 代码,参考内置模块控制器部分。
在项目的根目录下建立文件/auth/client.js
,实现一个根据 http 请求 返回Clinet
对象的方法。
通过调用/auth/authorize
获得access_token
,它的值和client.js
返回的对象存在一一对应的关系。
获得的access_token
会存储在 Redis 中,有效期是7200
秒。格式为应用名称
(app.js 中的 name),内容名AccessToken
,token字符串
,用户id字符串
(来源于 client.js 中指定的 id),中间用:
分隔。
tms-koa-0:AccessToken:c89d35281105456babd15d94831424c7:userid
利用这个机制可以用
tms-koa
实现一个基于 token 的 api 鉴权中心。
通过调用/auth/client
用access_token
获得用户信息。
详细说明参加:访问控制
项目根目录下创建controllers
目录,路径和 url 匹配
需要从 Ctrl 类继承。
const { Ctrl, ResultData } = require('tms-koa')
export class Main extends Ctrl {
tmsRequireTransaction() {
return {
get: true,
}
}
get() {
return new ResultData('I am an api.')
}
}
// 注意,必须要默认导出
export default Main
tms-koa
会根据url
自动匹配/controllers
目录下的控制器文件。
路由格式:http://yourhost/{prefix}/{controller}/{method}
参数 | 说明 |
---|---|
prefix | /config/app.js 文件中,router/controlers/prefix 中指定的内容。 |
controller | 和/controllers 目录下的文件对应。main.js 作为目录中的默认控制,如果url 匹配的是目录,tms-koa 会尝试匹配main.js 文件。 |
method | 匹配到的Ctrl 对象的方法。 |
参考:/lib/controller/router.js
文件。
项目根目录下创建public
目录。
在控制器类(Ctrl)中添加方法,说明需要在调用接口前执行的代码。
async tmsBeforeEach(method) {
// 返回ResultFault及其子类的对象,终止接口调用
// return new ResultFault('发生错误')
return true
}
domain bucket path
domain 和 bucket 对用户是不可见的?但是要直接访问呢?
需要在部署阶段创建程序运行后用到的domain
,例如在files
目录下创建tests
目录,用于保存单元测试产生的文件。
在 controllers 目录创建文件 upload.js(可根据需要命名),用于上传文件。
const { UploadCtrl } = require('tms-koa/lib/controller/fs')
class Upload extends UploadCtrl {
constructor(...args) {
super(...args)
}
}
export default Upload
上传文件 api:http://localhost:3001/api/fs/upload/plain
在 controllers 目录创建文件 browse.js(可根据需要命名),用于浏览文件。
const { BrowseCtrl } = require('tms-koa/lib/controller/fs')
class Browse extends BrowseCtrl {
constructor(...args) {
super(...args)
}
}
export default Browse
安装依赖包
cnpm i log4js -S
在启动代码中添加如下文件
const log4jsConfig = require('./config/log4js')
const log4js = require('log4js')
log4js.configure(log4jsConfig)