前言:Nodejs很火,但是好像工作中很少见到大面积的招聘岗位。我也用了nodejs写web服务很多年。分享一套我用了很久的代码,我觉得挺好。有需要的朋友拿去看看,我们不去纠结到底nodejs好不好,适不适合做Server,这些问题,吵翻天有何意义。能解决问题就好了。
开发快也是一种优势,现在中小型创业公司,底子差,业务要求快。加上云服务商的api加持,为何我们还要维护一个笨重的服务体系。当我需要AI服务的时候,我就接入AI服务商的接口就好了。我需要cdn服务的时候我接云服务就好了,我需要支付的时候我调用支付服务API就好了。那么一个小巧,快速的业务方案就会让创业型企业快速铺开市场,2-3个月就可以快速上线。尤其是在小程序盛行的今天,都不用笨重的APP了,云开发也是不错的选择,但是企业总要有一定的数据和业务能力,不然也会被云开发商掣肘。
今天分享的就是一套代码,会放到github上,github.com/vincent-li/… 大家下载还需要根据项目调整配置文件。不敢说是非常牛逼,我从来都是土狗一个,看看各位如果没有思路的朋友,是不是可以拿去直接先把业务干起来。废话不多说。代码走起。
思路比较简单待我一步一步拆解。我把nodejs定位就是web服务程序,不要跟我讨论底层稳定性的问题,因为我利用云服务商全部解决了。服务框架用的是koa,数据库是mongodb,那么我们来讲讲一个web服务到底需要什么。
- web服务最基本的是接收请求,查询数据库,返回结果给客户端。此类功能在controllers下面完成。
- 上传文件,利用一个插件multer,www.npmjs.com/package/mul…
- 静态文件服务,我会提到,但是还是不要写在服务器上面,讲过了,nodejs还是能力有限。利用cdn接口。
- 登录验证逻辑,利用session来做。有人说咋不用token,一个意思,只是放的位置不一样。
- log分析,利用守护进程pm2的log能力,具体后面讲。
讲了一堆估计没做过的人看懵了,不急,看看代码就明白了。入口index.js文件
1 | php复制代码const Koa = require('koa') |
入口的js就是引入koa和一堆koa的插件,然后根据api装配起来就OK了。
由于项目都有各种环境,所以要根据启动环境把不同的配置项加载进来。const _config = require(‘../config’),配置项中包括一些敏感的数据库连接账号和密码,我都替换掉了。所以各位在开发的时候,不建议把production的配置上传到gitlab,最好是运维持有并配置。
1 | javascript复制代码const port = Number.parseInt(process.env.PORT) || 6060 |
利用global把一些通用的库加入到开发体系,就不用一遍一遍的引用了。这里把lodash引入,我觉lodash的方法足够我们用了。还有加密算法crypto,其实做的久了,基于业务的所有开发都是各种成熟组件的装配。解决方案都很成熟,所以我不认为有难做的业务,至少难不在技术,而是产品形态。
为啥把models作为global全局,因为这块是可以独立于koa初始化的,也没有必要纳入整个koa的请求上下文,但是业务处理的时候又要频繁使用,那么干脆初始化到global里面,随时取用。
1 | ini复制代码const mongoose = require('mongoose') |
简单的不要不要的,就是把config里面配置的连接字符串,放到组件的方法里面,mongoose.createConnection,mongoose是用的比较好的mongodb连接组件,每中数据库都有相应的js帮助做操作。我比较喜欢mongodb是因为跟json结构完美契合,理解上比较一致,操作也基本符合js的操作规范。不用写sql真的舒服。随便找一个数据对象看下大家就明白了。
1 | javascript复制代码const model = { |
name就是数据库中对应的表名,也是调用的时候的名字。跟文件名可以不一致。文件名我叫_user,name:user,调用的时候是model.user,非常方便。里面的字段名称和类型对应mongo的collection,也就是表。也可以跟对象和function,具体操作可以去看www.npmjs.com/package/mon… mongo的官方操作方法都支持,具体要看mongoose的版本和mongodb的版本,官方有的都可以用。创建完model就可以在方法中使用 await model.* 的方式调用了。方法是异步的,前面要加await,不喜欢可以直接调用同步方法。不建议,毕竟有语法支持,又不难理解。
回到index.js,后面的设置静态目录,设置模板,就比较简单,模板就是js的入口页面,为啥把js的入口放到服务,而不是做成静态放cdn,nodejs就是做静态渲染的,目的就是可以很好的把数据注入页面,所以js入口自己做方便很多。session这块要讲一下,这个图省事,大家都session概念不了解的麻烦自行阅读相关资料。这里的session模块干了几件事。
- 在koa ctx上下文中注入一个session对象,ctx.session = {},可以把登录信息全部放进去。比如
1 | ini复制代码 bo = { |
- 自动把ctx.session中的数据存储到指定的数据库,这里就用的mongodb,这样做就不会因为服务宕机造成登录信息丢失。
- 根据配置,在session超时之后清除session信息。
所以我们只要做一个全局的过滤器,每次检测ctx.session中有没有登录的信息就好了。比如userid,userid为空就直接redirect到login页面就好了。
下面就剩一个就是处理请求了,这才是web服务的重头戏。我们利用bodyparse插件,将所有请求过滤一遍,把请求参数整理成json对象。
1 | less复制代码// 解析报文的body |
然后就可以在ctx.request.query或者ctx.request.body中取用。ctx.request.query代表的是get请求的参数。ctx.request.body存post请求参数。当然也可以处理head,put,delete等请求。其实我觉得用不到。各位自己看。
1 | php复制代码/** |
以上就是一个路由定义的方法,prefix表示统一的前缀。post就是方法名,意思就是初始化了一个接口,访问路径就是/api/user/smscode,具体看代码,对应的执行方法就是sendSmsCode,这就是一个向用户端发送短信验证码的接口。当然短息我不用写,直接用云服务就好。我用阿里云的短信接口,发的66的。
1 | javascript复制代码const sendSmsCode = async (ctx) => { |
大家自行看代码吧,懒得讲太多,很多东西上面提到过。这个代码基本上是可以跑起来的,但是呢,我上传的代码是修改了关键信息的,如果希望接数据库就把自己的数据库参数输入。具体的看配置文件。当然希望你很会玩代码,自行排查一些问题。没那个闲功夫的就看看文章就好了,其实业务层,根据很多公司的业务发展不一样,需要不一样的代码,还是那句话,产品形态决定代码形态。
精髓就是,站着云厂商的肩膀上,快速把自己业务落地,AI类的我喜欢接百度,语音分析接科大讯飞,服务器、存储、云数据库、短信接阿里云,IM一般接腾讯,毕竟小程序场景还是微信生态稳。我的创业经验就是,小程序(微信)+Nodejs服务+阿里云企业服务+腾讯智能服务,麻溜的干业务,之所以没有成功,就是特么这个操蛋的创业环境。
各位看官仔细想想,在云服务商竞争激烈的今天,给了很多小而美的企业生机。以前要想做到的事情需要各种各样的人才,耗时耗力,关键还未必做的好。现在大部分都是调用现有的云服务,我们小企业就做好自己的业务,方便又快捷。而且我不用讨论什么压力,什么稳定。我把安全稳定的问题全部用分润的方式,利用云服务上的能力解决了。是!我啥底层都不懂,但不妨碍咱们成为一家企业的顶梁柱。未必比一些人差,很多专注于技术的人员,不但没有解决企业的问题,还增加了企业的负担,最后还是说企业这没有那没有。想想问题在哪?牢骚两句,看官自便。
本文转载自: 掘金