平台化框架
基于express 上面封装的一层框架,主要以配置贯穿项目,比较灵活,强化了MVC了思想,尤其Model层级上面
项目特点
- 1 Model(接口层) 以配置为主
- 2 项目中最好禁止使用require(./XXXX)自定义模块,为了支持服务器打包,变换目录 ## 文件目录
#举个栗子 实现一个用户注册的功能
Model
新建一个interface.js
module.exports={
namespace:"User", //命名空间
apis:{
register:{
title:'用户注册', //标题 用于日志统计
url:'/user/register',
params:{
firstName:{type:String,require:true,default:'wei'},
LastName:{type:String,require:true},
fullName:{type:String,require:true},
yaoQingCode:{type:String,require:true},
regTimeguid:{type:String,coerce:function(value){
return Date.now().toString()+"-"+this.fullName+"-"+value;
}}
}
},
checkUserName:{
title:'检查用户名称是否重复',
url:'/user/checkUserName',
params:{
fullName:{type:String}
}
},
checkYaoQingMa:{
title:'检查邀请码',
url:'/user/checkYaoQingMa',
params:{
yaoQingCode:{type:String,required:true}
}
},
//接口的定义可以为JSON对象,也可以为function,作为function的时候,参数req,callback,req你懂的,callback是接口返回的数据入口.
//如果你要调用其他模块接口,你就在后面继续加参数,比如User,Role,单词一定不要写错了。所以从某种角度来说,你可以不用require 了
User_fuzha:function(req,callback,User,Role){
var firstName=req.param("firstName"),lastName=req.param("lastName")...;
//如果需求简单的话
User.register({firstName:firstName,lastName:lastName,...}).done(function(res){
//callback接收两个参数,第一个为错误,第二个为成功的结果
return callback(null,res)
},function(err){
return callback(err,null);
})
//如果需求复杂的话,比如在注册的使用,需要验证用户名称和邀请码
//用户名验证和邀请码可以同时请求,类似promise.all一样
User.checkUserName({xxx:xxx}).checkYaoQingMa({xxx:xxx}).done(function(res1,res2){
//todo
User.register({xxxx}).done(function(res){
//当然业务还可以在复杂一点,你需要调角色模块的,一个方法
Role.xxxxx().done(...)
return callback(null,res);
})
},..)
},
userInfo:{
title:'用户信息',
url:'user/userInfo',
param:{
userid:{type:Numebr}
}
}
...
}
}
apis 接口属性介绍
属性 | 类型 | 说明 |
title | String | 主要用于代替注释,而且在日志中会备用,最好必选 |
url | String | 接口请求地址,必选 |
domain | 接口请求的域 | 可选,这个值一般在node启动的js中进行全局配置 |
methord | 请求方式,默认post | 请求方式 |
params | 参数 | 参考下面 |
params 属性介绍
属性 | 类型 | 说明 |
type | 类型 | 数据类型,会帮你转换,比如你前台传了“1”,type设置为Number,那接口接收就是1 |
require | 默认fasle | 表示字段必选 |
default | 在没有传递的情况下,字段默认值 | 可以为字符串 |
coerce | function 类型 | 用于处理接收值,在Function内部使用this,可以获取其他字段值 |
Controler
正常情况下打开一个页面
module.exports={
// "common.login" 为虚拟路径,注意以点隔开
//"User_userInfo" 接口规则命名空间+“_”+"接口名",名字这么起,也是无奈的选择
app.get("/login","common.login");
//打开一个页面,并且调一个接口,进行页面渲染,function 这个参数可以省略
app.get("/index/:userid","common.index","User_userInfo",function(user,req,res){
//user 为 User_userInfo 的接口返回的结果
//req 为就是express 的req,res 同理
//比如在某种情况下,你需要调用res里面的方法,比如json ,end等等,应该这么写res.myJson(..);
//规律 res.my+首字母大写+后面的部分。如果你直接用res.json 原声的,他可能会爆一个错,不过这个错不会影响结果,建议不用
});
//当然我们也猥琐了一下,如果这么使用,页面就使用vue模式进行加载渲染,这是黑科技
app.vue("/login","common.login")
//直接返回结果
app.post("/login","User_login");
//如果需要对接口结果进行处理,加Function
//比如
app.post("/login","User_login",function(data,req,res){
return data.message
})
//当然你请求可能需要调用两个接口
app.post("/xxxxx",["User_A","User_B"]);这么写会直接返回{User_A:XXX,User_B:XXXX}
//当然你请求接口,可能需要小小的修改,相信你已经想到了,加一个function
app.post("/xxxx",["User_A","User_B"],function(a,b,req,res){
a.child=b;
return a;
});
//也许你请求一个接口可能比较复杂,可能有相互的依赖关系
app.post("/reqgist","User_fuzha")
}
View
无话可说,非常讨厌handlerbar,给我洗了
后记
以上介绍就是随便说说,有很多也没说,说的也没讲到位,我个人觉得框架本身就是一个思想支撑的。所以并不一定会完美的应用于任何一个场景
也就是随便说说,意思希望大家能够理解,配置本身就是不灵活,这个框架就在灵活和配置找一个点来贯彻项目。因为项目中没有require,所以我们可以为所欲为的“服务端打包”,运行npm run build,server文件夹就是服务端打包的结果,看起来是不是工整许多呢。