背景说明
前端这几年一直被主流的三大框架所引导,MVC和MVVM等名词相信大家也并不陌生,我最早接触到框架是2016年,当时用的是AngualarJs1.5.8的版本,这个版本也是组件化的开始。我们会把页面的一部分试图和它对应的逻辑抽离成一个组件,一方面是隔离上下文,另一方面是为了多处复用。
当时写一个组件,大概包括一下几个部分:
1.一个view的template模板,基本上由原生的html以及自定义的组件构成,主要负责页面视图和事件绑定。
2.view对应的controller控制器,来处理页面中的主要逻辑。
3.service/factory用来处理controller中从后台获取的数据,以保证controller只处理业务逻辑,不包含其他逻辑。
4.constant用来集中统一的管理service中需要使用的常量。
当然在全局,也有一个util和config文件夹对整个工程以及通用配置和工具做了封装,以便业务中多出复用。
说了这么多,其实也是最近在学习koa2来构建后台服务有一些感悟,软件开发设计,前后端都有类似的经验,人们在使用中可能需要各种调用,数据传来传去,看起来很复杂,但是当你到达一定的阶段,就会感悟到这些分层的设计,其实是为了更方便项目的管理和维护,也更科学的进行项目开发和使用。
- 废话不多说了,我们来看看一个koa2的后台服务需要怎么进行架构设计。
koa2项目结构简述

- node_modules
- bin
- www
- src
- routes
- api
- view
- controller
- service
- middlewares
- views
- config
- util
- db
- public
- validate
- cache
- routes
- app.js
- test
- package.json
- eslintrc.json
- .eslintignore
- .gitignore
- README.md
在这个koa2的项目中,在koa-generator的基础上,持续优化了项目的结构,首先
- node_modules和package.json我就不过多介绍了,其实就是管理整个项目依赖的nodejs中使用的模块包。
- bin目录其实是整个koa2服务的入口,它的作用就是纯粹的搭建一个http-server
- app.js中,就注册了koa2的http-server所需要的一些插件,例如处理postData,处理cookie-session,处理日志,处理异常捕获等。也就是因为这些插件,我们才不需要对http-server做这些基础的设置。app.js中,我们引入了koa-router,也就是路由。我们通过http请求后台资源,也就是通过路由来映射资源关系。
- src目录中,包括了:
app.js中对路由的分发routes(包括json的数据返回api目录和html页面的返回view目录);
1 | // 引入定义的两类路由 |
middleware对应了app.js中在分发路由的时候,需要使用的中间件函数,处理中间异常场景;
1 | // 用户信息校验 |
validate则是使用json-schema对用户的输入数据进行格式校验。
封装ajv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/**
* @description ajv对定义的schema校验
* @author unclePis
*/
const ajv = require('ajv')
const ajvInstance = new ajv({
// allErrors:true // 输出所有的错误(比较慢)
})
/**
* json-schema校验
* @param {object} schema 校验规则
* @param {object} data 带校验的数据
*/
let validator = (schema, data = {}) => {
const valid = ajvInstance.validate(schema, data)
if(!valid) {
return ajvInstance.errors[0]
}
}
module.exports = validator根据json-schema语法定义schema
1 | const scheme = { |
- 使用ajv对定义的schema进行校验,并抽离成中间件
controller对应了api中需要对路由的处理;
service对应了controller中需要对底层数据库获取数据的处理以及统一数据格式化输出;
1 | /** |
views中是ssr后端模板渲染使用的一些ejs的模板,在一般的基于restful的前后分离的项目中,都是通过json进行通信的,可能用不到这部分。
- 具体参考
服务端ssr之ejs模版
config则是对mysql/redis数据库进行连接的基础配置,以及对于项目中使用的const常量和一些密钥的统一管理配置。
db则是对mysql数据库,使用sequelize进行ORM的数据建模。
- 具体参考
sequelize - 数据建模以及数据同步和sequelize - CRUD增删改查两篇文章,有详细介绍
public是整个项目中使用的静态资源的托管
cache是对redis来缓存用户数据的配置
1 | /** |
util 则是全局通用的工具方法,例如使用nodejs的crypto对密码进行Hmac加密/和获取环境变量等。
1 | /** |
- 剩下的文件包括jest进行单元测试的test目录,以及eslint对代码风格统一的配置,以及git进行版本管理的配置。
总结
到这里,一个项目的结构也就完整了,其他的也就是在处理不同的业务,跟底层数据库的一些交互。