# Node.js 后端思路 [TOC] ## 满足前端需求 后端要满足前端需求。如何满足呢?考虑数据的传递。 前端需要一个功能,作为后端开发要思考实现该功能所需什么数据结构(interface),是否需要持久化存储(database)以及临时存储(redis)。 后端和前端最多的信息交换就是**数据**。一切行为都是通过请求接口返回的数据进行沟通。 知识点: 1. 这个过程要跟前端规划,看前端需要什么功能,就能思考出需要什么数据了。 2. 有了**数据**,就要思考**存储**。 3. 有了**存储**,就要思考**传输**。 比如 **RESTful**, 最常见的接口方式,想好每个功能需要怎么传数据,写好 API 接口就行了。举个例子。 **GET** `/api/models/{id}` ```typescript { id: number; name: string; tags: Tag[]; modelVersions: ModelVersion[]; } ``` 上面例子,`id` 用来区分模型、`name` 用来便于查看、`tags` 和 `modelVersions` 是复杂的数据结构,携带更多的信息。 有了一个接口和数据结构的思路,就能顺势思考出数据库该怎么写。至此我觉得,后端的功能已经完成一半了。 ## 流程便于维护 - 多任务、多实例并行 - 多服务器部署 - 多种不同场景 以上考虑**配置文件**。 - 繁琐的部署 - 繁琐的配置测试环境 - 繁琐的依赖关系 以上考虑 **CI/CD**。 - 难以得知任务详细信息 - 难以得知服务器状态 - 难以得知任务成功与失败情况 以上考虑 **日志与监控**,不是得配置框架,手动 `logger` 然后手动上去看日志也行。 - 需要开机自启 - 需要出错自动重启 - 需要多处配置相同的启动方式 以上考虑 **守护进程(pm2),系统任务(systemd),云服务镜像**。 ------ ### 注:CI/CD 持续集成与持续部署 一般指的是一套写好的脚本,会在每次提交代码的时候执行。 一套好的 CI/CD 脚本应该做到**持续集成(CI)**,也就是你的代码可以在到代码仓库的时候推送到服务器。 好的例子: - `git push` 之后,设置了 GitHub/GitLab 的 CI 脚本自动推送到服务器。 - `git push` 之后,本地执行了一串 `ssh` 命令帮你 `scp` 代码到服务器。 坏的例子: - `git push` 之后,先打包源代码,拷贝到服务器上,解压,覆盖。 然后做到**持续部署(CD)** 好的例子:推完代码,等 5 分钟就能打开线上环境看结果了。 坏的例子:推完代码,手动 `ssh` 上去更新依赖、编译文件。 ## 想到什么写什么 常用工具: - **RPC**:内部服务之间传递数据。 - **ORM**:操作数据库。 - **JWT**:登录认证。 - **Nest.js**:很舒服的结构: - 接口(endpoint) 放在 controller 里 - 服务(service) - 数据(model) ---- 装饰器(decorator)、处理器(processor) 是一种东西。当有一个数据、逻辑需要经过预设以外的处理,就可以抽出来单独写一个文件来做这件事情。 ---- 对于需要依次执行的任务,需要一个**队列(queue)**。这时候用一个框架(比如 `bull-mq`)会方便很多,它们会有现成的面板提供监控。 任务要具有唯一性,代码层面需要支持「增查」,但基本不「删改」。 如果写队列,就先写 consumer,然后想想 job 的流程是什么就行了。 ---- 需要持久化存储、方便查询就存 SQL。 需要「能一直把数据存在内存里」就用 Redis。 需要别的应用程序访问就直接写文件。 ---- 调试错误、上手别人的项目: 先思考一个请求的流程,从哪里调用了哪里的功能?(经常需要打个断点或者 log,确保自己想的对) 再思考我想改的功能是从哪里开始写的,我是改那里的逻辑就好了还是外面再包一层。 如果是个 bug,几乎大部分情况是条件语句有问题。什么 `if (!isLogin) logout()` 这种阴间错误。