1、技术栈
Pm2:node进程管理工具
Restify: 基于Nodejs的REST应用框架
sequelize: 基于Nodejs功能强大的异步ORM框架
swagger:Api配置工具及可视化文档
2、文件结构
/package.json:项目依赖与配置。
npm run dev;执行pm2启动命令做进程守护,具体服务配置在ecosystem.json
/ecosystem.json:配置分为两部分。
Apps 服务。name: 服务的进程名称;instances:启动进程实例数量;script:执行启动的脚本文件;env[_pre]:环境变量配置。
Deploy 部署。User,host,path:配置部署目标服务器的域名路径及用户;repo,ref:代码仓库及分支;post-deploy等:代码部署前后执行的脚本和启动命令。
/base:服务器架构的核心部分
根据环境变量提取config项目配置,
启动配套的数据库等services服务,
加载middleware中间件,
注册routes路由及相关的controllers控制器逻辑,
启动服务器监听。
/services: 启动前需要初始化的服务
邮件发送:使用nodemailer模块连接服务器,输出Mailer对象,挂载在this.servie对象上,提供sendMial方法。
Mysql初始化:使用sequelize模块初始化连接数据库,输出Mysql.db, 挂载在this.servie对象上,提供sequelize实例的方法。
/middleware:自定义的中间件
auth.js:api权限校验,对应于route配置中meta.autu和privilege_menu_id,为true时进行校验,获取保存在session中的permission权限,是否含有对应的privilege_menu_id。
/config:
app.js:业务逻辑所需的配置,启用的modules模块。
db.js:mysql、redis数据库域名,端口,用户密码配置
mail.js:邮件服务器连接配置
server.js:http应用监听的域名和端口
2.1 MVC
/routes:
公共的api路由定义,遵照swagger的配置格式,可在注册router与controller同时,生成动态的在线api文档。
file.js:
mete.use:是否启用;mete.auth:是否需要权限;mete.privilege_menu_id:权限id
controller.name:对应的控制器文件名;controller.action:控制器实例的方法;
/model:
公共的数据模型,sequelize对象关系映射的数据库配置。
对应于数据库中各个表的定义以及关联关系
/controllers:
公共的控制器类文件
file.js:
所有的控制器实例化后,以文件名为key挂载到controlers对象上,当做参数传入控制器实例的方法中,方便控制器逻辑的互相引用。
按照routes/file.js中,路由与控制器的method、path、controller配置,注册到restify的应用中。
引用对应的models数据表,按业务逻辑操作数据库。
/modules:数据服务模块
/config/app.js中modules配置的数据服务模块。同样包含routes,models,controllers
/ge_front与/views:前端静态文件资源。
在ge_front中进行前端开发,构建打包后的文件全部导入views中存放。
/file: 上传文件的存放目录
3、services,中间件,路由控制器的提取注册
controllerManager.js:
从config/app中提取出公共controller与modules服务模块配置目录,
使用fs文件模块读取目录下的所有文件名列表,
动态require加载controller脚本文件,并实例化
以文件名为key以单例模式挂载在this.contrlllers上
router.js :
动态提取路由的配置信息后,与controllerManager上的控制器对应注册到restify服务中
封装执行控制器
根据路由配置,获取对应的controller和action
将action中的this绑定为ctr上下文对象,reques,response,next,params;以及所有当前controller对象;
统一做返回报文的封装,报错捕获,也可自定义返回报文。
4、具体服务实现
1、 controller类的实现
继承自一个base类,将公共的action方法放于base父类中,方便调用。
Base类实现actionCall(controllerName,actionName),实际运行中,action可以调用其他类中的action,实现方法复用。
2、文件上传下载
multipartBodyParser中间件接收报文实体中数据,保存到file目录下,返回文件名,和文件路径。
下载根据请求的文件名和文件存储目录,找到具体的文件,创建文件可读流,导入response,返回一个promise,在文件流end事件后resolve({isDownload: true});
3、 单点登录及权限验证
使用公司统一的单点登录,跳转登录页
登录返回页面后,调用验证接口
获取ticket标识cookie信息,在服务端向单点登录服务器请求验证
通过验证则可以获取当前登录的用户信息
查询权限配置数据库,将权限保存在session中,便于路由方法的使用