「我的个人助手」主要用于为用户提供一些日常使用的小工具,包含天气查询、日程管理、事项提醒等功能。
仓库(当前仓库)地址: life-helper-backend
技术栈: Node.js
+ Nest.js
+ TypeScript
+ Typeorm
+ MySQL
+ Redis
+ Docker
仓库地址: life-helper-miniprogram
技术栈: 原生小程序
+ 自定义的一套框架加强工具
仓库地址: life-helper-frontend
技术栈: Angular
+ TypeScript
+ Sass
+ RxJS
+ Swagger
+ Webpack
Web 地址: 我的个人助手
以下是当前项目的技术架构,可供读者参考。
本地开发环境主要用于新功能开发的前期阶段,就在当前开发的电脑部署环境,MySQL
和 Redis
等服务也是自建的。
本地开发到了较为成熟的阶段,会将代码进行提交在测试环境部署,测试环境用的是一台低配具有公网 IP 的阿里云服务器,MySQL
和 Redis
等资源购买的是阿里云的服务。
预发布环境处理运行代码的服务器以外,其他服务直接连生产环境的资源,用于临上线前的最后一道测试。
- 尽量使用阿里云封装好的服务,缺点是贵,但有点是免运维,比自己部署稳定的多。例如:API 网关、负载均衡等中间件。
- 使用阿里云云效(
Codeup
)进行自动化部署,尽量避免手工上线。
- 服务端 URL:
https://api.lifehelper.com.cn
- 使用阿里云 API 网关 承接 HTTP 请求,不将内部服务器直接暴露在公网上。
- 使用阿里云 API 网关 自带的 摘要签名认证 对 HTTP 请求进行基本鉴权,保证只有我方客户端发起的 HTTP 请求才进行转发,其他非法请求全部进行拦截。
- 将合法请求转发至阿里云 负载均衡 。
- API 网关 后的所有服务,均部署在阿里云 专有网络 VPC ,与公网不互通。
- 尽量遵循 “低配多台” 的原则配置服务器,即:低配置的多台服务器的综合性能优于同价格的高配置服务器。
- Web 端 URL:
https://www.lifehelper.com.cn
- 使用
CDN
+OSS
的架构承接 Web 端服务。关于如何让OSS
支持单页应用请看这篇文章 —— 《如何让 OSS 支持单页应用》
- 根模块全局只有一个,路径
src/app.module.ts
。 - 根模块负责引入特性模块和配置全局中间件。
- 按照对应功能划分模块,以模块为单位进行封装,该模块称为 “特性模块”。
- 特性模块放在
src/modules/
目录下,每个模块一个同名目录。 - 该功能对应的
controller
,service
,model
,interface
等文件等放置在该特性模块内,无需再建二级目录。 - 不要在特性模块的控制器(
controller
)中直接使用共享模块的服务,而应该自建一个服务,在该服务内使用共享模块的服务,哪怕只有一行代码也要这样做。 - 每个
*.controller.ts
均对应一个同名*.dto.ts
文件,该文件下均使用类(class
)进行定义。 - 特性模块之间不允许相互引用,只允许引用共享模块。
- 将可能被多个特性模块用到的服务以及涉及第三方 API 的服务剥离出来,统一放置在共享模块下。
- 共享模块目录
src/shared/
。 - 共享模块中的每个服务均需要完整测试用例。
- 共享模块仅被需要的特性模块引入,不要引入根模块。
- 共享模块内不得建立
*.controller.ts
和*.dto.ts
文件。
- 以特性模块的 业务名 作为目录名称,一律使用 小写 英文字符,使用短横线(
-
)分隔,所有该业务相关文件均放置于该目录下。 - 业务模块内应至少包含一个控制器,以及和控制器同名的 DTO 文件(
*.controller.ts
和*.dto.ts
文件一一对应)。 - 比较大的子模块应新建子目录。
目录示例(假设业务名为 my-feature
):
my-feature/
│
├── my-feature.service.ts # 主要
│
├── my-feature-a.controller.ts # 控制器,每个业务模块至少对应一个控制器
├── my-feature-a.dto.ts # DTO 文件,与同名控制器一一对应
│
├── my-feature-b.controller.ts # 控制器,每个业务模块至少对应一个控制器
├── my-feature-b.dto.ts # DTO 文件,与同名控制器一一对应
│
├── ...
│
├── feature-one/
│ ├── feature-one.service.ts
│ ├── feature-one.interface.ts
│ ├── feature-one.entity.ts
│ └── feature-one.model.ts
│
├── feature-two/
│ ├── feature-two.service.ts
│ ├── feature-two.interface.ts
│ ├── feature-two.entity.ts
│ └── feature-two.model.ts
│
└── ...