浅谈用 node.js 开发后台 api 的要点
作者:草梅友仁
前言
前段时间为了统计下开发的插件的使用情况,于是为此开发了相应的后台。
自我感觉这是我写的最好的、架构最清晰的一次后台。
和以前比也有了不小的进步。
虽然后台还没有开发完毕,还有些想法没有实现,但是先写点下来,以免以后忘记了。
一、项目目录
本次最主要的进步是对于项目目录进行了合理的划分,使用了常见的 routes、controllers、services 划分,具体的可以见图片。
根目录也没啥好说的,都是些项目基本配置,重点还是在 src 目录里面
下面来逐个解释文件/文件夹的用处
- bin 用于存放项目启动脚本,里面只有一个 www.ts 文件,是服务的入口。这个是 express4 的惯例,在此保持一致
- config 配置项,将一些配置抽离出来单独管理,有利于维护
- controllers 这个地方主要用于处理进来的 Request 和返回 Response
- db 存放数据库操作。本项目用到的数据库为leancloud,可以免费使用的云数据库。由于使用了云数据库,这里只有初始化操作。如果使用本地的数据库可以在这里封装数据库操作。
- middleware 中间件。用来对验权、限流等操作
- models 模型。用来存放实体类和返回的数据结构。这样有利于统一数据交互的结构
- routes 路由。进行请求分发,调用 controllers
- schedule 存放定时任务。比如每隔一小时进行一次统计
- services 业务逻辑。实际处理业务逻辑的地方。注意,此处不应该操作 Request 和 Response,数据处理应在 controllers 完成。
- utils 工具类。一些通用的方法、函数可以放在这里
- app.ts express 的配置。
可以说,对项目进行合理的划分,就已经是成功的一半了
实际上本次开发也进行的非常快,除了项目本身就不是很大以外,合理的架构也让我事倍功半。
二、自带 api 文档
本次项目的另一个有趣之处使用了 swagger-ts-doc、swagger-ui-express 来生成 api 的文档,既方便调试也方便 debug。
具体的使用可以直接去搜下 swagger 的使用方法
(当然,这也不是自动生成的,而是你要写一些装饰器和说明)
三、对每一个调用 api 的请求进行鉴权和限流
本项目的限流使用了 express-rate-limit 这个模块,也比较方便。
(由于服务器是个小水管,因此设置的 QPS 很小。。)
鉴权实际上采用的是 id-key 设计
参考了 leancloud 的设计思路,也就在 Request 的 header 中添加鉴权信息。理论上讲用 https 发起请求本身也比较安全,但为了更加安全,因此需要对 key 进行加上时间戳的 hash 作为 sign 来校验,具体的 hash 算法可以自己设计,只要每次请求的 sign 都不一样就 ok 了。当然了,考虑到彩虹表的存在,key 也不能太简单,不然别人还是能通过 hash 来反向推出 key 的
四、使用统一的 api 风格
虽然在设计之初是想用 rest 风格的,不过很遗憾,搞到最后也没能实现 rest 风格。在接口设计上还是保留了一些自己的习惯,在此就不献丑了。总之,一个项目中的 api 风格肯定是要统一的
五、使用 TypeScript
实际上用 js 也行。不过一旦用过 ts 就回不到 js 了。ts 意味着强类型,但完全兼容 js,在大型项目上十分好用。随着 js 的日新月异,可以说一个没有编译的 js 项目已经不存在了,既然如此,那么直接用 ts 来写岂不是更加美好?强类型意味着静态校验、自动提示。而且类型本身就是一个最强的注释,基本上只要看到这个类名就知道这个类是干什么的了。
本次项目应该是本人第三次使用 ts,效果拔群
六、使用云数据库 leancloud
- 由于服务器的内存实在太小,如果挂个 MySQL 或 MongoDB,内存分分钟爆炸,因此使用了leancloud。面向对象的非关系型数据库十分适合 js、ts 这样的语言来开发。而且文档齐全,官方也是强推,比较好用。与 MongoDB 比较类似,我估计它的底层就是 MongoDB。常见的语言基本上都封装的相应的 sdk,用就完事了。
- 后来又在本地安装了 MongoDB 来减少云数据库的调用次数,MongoDB 和 leancloud 用法十分类似,与 node.js 十分搭配,因此选定了 MongoDB
七、使用 server-chan 来监控服务器错误
本次项目还有个有趣的东西:server-chan 。一个免费的可以推送消息到你的微信的工具。由于没有找到喜欢的 npm 包就干脆自己写了一个,叫“node-server-chan”。功能也很简单,只有一个类,两个方法,分别是初始化方法和推送消息方法。
1 | import { ServerChan } from 'node-server-chan' |
后记
好了,先写到这里,以后有了新的想法再改吧。。
- 首发——2019/9/3
- 增加了关于 MongoDB 的部分——2019/9/20
本文作者:草梅友仁
本文地址: https://blog.cmyr.ltd/archives/ddd5e287.html
版权声明:转载请注明出处!