当写一个前后端分离项目时需要注意什么
近些天,我爆肝了一个使用 NextJS + Cloudflare Workers + Cloudflare D1 数据库构建的前后端分离的类似 Memos 的网页应用(TSUKKOMI 在线预览)。到现在为止,大概是我第三次写全栈应用了,但老实说,我对全栈一无所知,在写的过程中也还是出现了很多没有预想到的情况,因此写下这篇文,权当记录和分享,当想写一个前后端分离的项目时,我应该注意什么?
1. 在写代码之前
在写代码之前,有几件事值得仔细思考一下。
首先是技术架构,确认好要按使用的前端框架、后端服务、数据库和存储服务。以及要使用何种风格的 API,是否要生成 API 文档(比如使用 swagger 等工具从代码里构建)。
然后是数据模型,确认好项目设计的数据模型,在我的类 Memos 应用里,主要设计的数据模型包括 User、Memo、Label、Session(存储会话)、ResetToken(用于重置密码),在构建数据库的时候注意主键类型,使用自增 id 还是随机生成的 id(使用 nanoid 等库)。在这一步应同时确认好将会使用的授权认证方式。
接着是 API 的设计,考虑好将来要是用到的功能,从注册开始,登录、查询 Memos、新建/更新 Memos,到最后的重置密码等功能,思考完一圈,差不多就能汇总所有要用到的 API 了。如果要设计搜索的话,考虑好要传入的参数。
最后,差不多可以开始写了。
2. 开始写吧!
建议先开始写后端,因为前端的调试基本都依靠后端服务来进行。
后端项目应把不同作用的代码放入不同文件夹,一个常见的分层发放时为 控制层(路由,接收前端请求,参数校验)-服务层(处理核心业务逻辑)-数据访问层(SQL)。
一般来说,可以从写用户授权所需的 API 开始,依照在写代码前相好的 API 设计写下去就行了。几个值得注意的问题:
1、API 对时间的处理:后端最好统一存储 UTC 时间,在我的项目里,把相关的查询参数里的时间也限制为了 UTC 时间,API 返回 UTC 时间,最后再由前端进行时区转换。
2、API 对参数校验的处理:最好在一开始就想好 username、password 等需要的格式,然后封装好函数,在路由统一对参数进行校验。可以考虑使用 zod 之类的库。
3、如果确认要 API 文档的话,在开始写 API 的时候就应该开始做相关工作了。
API 的设计应确保:命名统一、返回格式统一、有统一的错误处理。
写 API 的过程中,可以使用 Hoppscotch 之类的工具,对 API 进行测试。
一个可选项是,对重要 API 如注册、重置密码进行流量限制,在中间件里对用户请求次数进行限制。
开始写前端。
首先是状态管理,前端需要存储当前用户等信息,可能需要用到状态管理的库,或者需求小的话,可以简单写一个状态管理就行。以及,如果没有使用组件库的话,应首先考虑好 Toast 和 Confirm Dialog 等交互确认组件的设计。
然后可以依旧从用户使用体验的链条来写页面,从登录注册开始。
还需要特别注意的是,前后端分离项目,应注意跨域问题的处理,这包括:API 请求的跨域、Cookie 的跨域、前端内容生成的跨域(如 Markdown 内容生成图片分享)。
最后,永远不要把重要的机密暴露在文件当中,应当使用环境变量写入系统,环境变量相关的文件如 .env 应只保留在本地开发环境中,在开源仓库中只存放 .env.example 之类的示例文件。