浅谈用 node.js 开发后台 api 的要点

作者:草梅友仁

前言

前段时间为了统计下开发的插件的使用情况,于是为此开发了相应的后台。

自我感觉这是我写的最好的、架构最清晰的一次后台。

和以前比也有了不小的进步。

虽然后台还没有开发完毕,还有些想法没有实现,但是先写点下来,以免以后忘记了。

一、项目目录

本次最主要的进步是对于项目目录进行了合理的划分,使用了常见的 routes、controllers、services 划分,具体的可以见图片。

mark

根目录也没啥好说的,都是些项目基本配置,重点还是在 src 目录里面

mark

下面来逐个解释文件/文件夹的用处

  • 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 的使用方法

(当然,这也不是自动生成的,而是你要写一些装饰器和说明)

mark

mark

三、对每一个调用 api 的请求进行鉴权和限流

本项目的限流使用了 express-rate-limit 这个模块,也比较方便。

(由于服务器是个小水管,因此设置的 QPS 很小。。)

mark

鉴权实际上采用的是 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

  1. 由于服务器的内存实在太小,如果挂个 MySQL 或 MongoDB,内存分分钟爆炸,因此使用了leancloud。面向对象的非关系型数据库十分适合 js、ts 这样的语言来开发。而且文档齐全,官方也是强推,比较好用。与 MongoDB 比较类似,我估计它的底层就是 MongoDB。常见的语言基本上都封装的相应的 sdk,用就完事了。
  2. 后来又在本地安装了 MongoDB 来减少云数据库的调用次数,MongoDB 和 leancloud 用法十分类似,与 node.js 十分搭配,因此选定了 MongoDB

七、使用 server-chan 来监控服务器错误

本次项目还有个有趣的东西:server-chan 。一个免费的可以推送消息到你的微信的工具。由于没有找到喜欢的 npm 包就干脆自己写了一个,叫“node-server-chan”。功能也很简单,只有一个类,两个方法,分别是初始化方法和推送消息方法。

import { ServerChan } from 'node-server-chan'
//SCKEY请前往 https://sc.ftqq.com 领取
ServerChan.init('SCKEY')
//标题必填,内容选填
ServerChan.noticeMaster('text')
ServerChan.noticeMaster('text', 'desp')

后记

好了,先写到这里,以后有了新的想法再改吧。。

  1. 首发——2019/9/3
  2. 增加了关于 MongoDB 的部分——2019/9/20