用户点击“提交订单”后,后端承担哪些工作?
用户选择地址、优惠券和支付方式后提交订单。
价格可能变化、库存可能不足、优惠券可能失效,外部支付也可能不可用。
后端验证身份、重新计算金额、检查库存、创建订单、调用支付并记录结果。
页面需要区分库存不足、价格变化、优惠失效、支付创建失败和结果确认中。
理解 API 后面的代码如何组织,以及 Service 真正负责什么。
订单与支付、消息与通知、项目与协作、账号与权限、文件与 Excel
后端是运行在服务器上的应用,负责身份、权限、业务规则、数据访问和外部系统协作。
页面背后的限制、流程和状态大多由后端决定,理解后端后才能看懂真实业务系统。
位于 API 入口与数据能力之间,是业务逻辑的执行中心。
Controller、Service、Repository、Entity、Middleware、Validation、数据库与第三方 API。
创建订单、审批流程、权限判断、计费和导出任务都由后端组织。
后端把用户请求转化为受规则约束的业务结果。
先看用户动作和业务风险,再理解技术为什么出现,以及它会怎样改变页面、状态和流程。
用户选择地址、优惠券和支付方式后提交订单。
价格可能变化、库存可能不足、优惠券可能失效,外部支付也可能不可用。
后端验证身份、重新计算金额、检查库存、创建订单、调用支付并记录结果。
页面需要区分库存不足、价格变化、优惠失效、支付创建失败和结果确认中。
后端验证身份与权限,检查输入,执行业务规则,读写数据库,调用支付、短信或 AI 等外部服务,并返回稳定的数据结构。
前端可以隐藏按钮,真正的权限仍要由后端判断。价格计算、状态流转和审批条件也应放在可信的服务端环境。
界面规则需要区分展示层约束与真正的业务约束,后者必须由后端兜底。
Java、Node.js、Python、Go 等生态都可以构建相似的后端职责。
先看用户动作和业务风险,再理解技术为什么出现,以及它会怎样改变页面、状态和流程。
订单完成后系统需要发送短信、邮件和站内信。
团队容易把技术选型当成产品能力本身,忽略接口契约、可靠性和现有运维体系。
不同语言运行在各自 Runtime 中,框架组织接口与依赖;依赖注入便于替换短信供应商和测试。
产品设计关注发送状态、失败重试和替代通道,底层语言通常不影响交互。
Spring Boot、NestJS、FastAPI、Django 和 .NET 提供路由、依赖注入、数据访问和安全等框架能力。技术栈会影响性能、团队招聘和生态工具。
学习全景时先看共同结构:请求进入、业务组织、数据访问、异常处理和部署。掌握这些结构后,切换语言更容易定位概念。
开发会议里听到技术栈时,先判断它解决的是语言、框架、数据库还是运行环境。
分层让请求入口、业务规则和数据访问各自保持清晰职责。
先看用户动作和业务风险,再理解技术为什么出现,以及它会怎样改变页面、状态和流程。
客服在订单详情点击退款并填写原因。
接口接收、退款规则、数据库读取和第三方支付调用混在一起,会难以测试和维护。
Controller 读取请求,Refund Service 检查状态和金额,Repository 查询订单并保存退款记录。
设计流程时把业务规则与接口状态对应起来,例如“已发货不可直接全额退款”。
Controller 读取 HTTP 参数并调用业务;Service 组织完整业务流程;Repository 负责查询和写入数据库。分层让规则更容易复用、测试和修改。
ProjectService.createProject 可能检查成员权限、生成编号、创建默认阶段、记录日志和发布事件。它调用多个 Repository 或其他 Service 完成任务。
设计流程图中的业务步骤,往往会在 Service 层变成可执行规则。
Service 层是代码组织概念;微服务是系统部署和边界概念。一个单体应用内部也可以有很多 Service。
同一业务对象在不同边界会有不同数据表达。
先看用户动作和业务风险,再理解技术为什么出现,以及它会怎样改变页面、状态和流程。
新建项目表单只提交名称和负责人,详情页却要展示成员数、风险数和创建人信息。
直接把数据库 Entity 原样返回,会泄露内部字段,也难以适配不同页面的数据需求。
Entity 对应持久化对象,DTO 定义接口输入输出,Schema 约束字段类型和必填规则。
设计数据结构时区分用户输入、页面展示、系统生成和敏感字段。
Entity 常对应数据库中的核心业务实体;DTO 定义接口输入和输出;Schema 描述字段类型和约束;View Model 可以专门适配页面展示。
直接把数据库所有字段返回给前端会泄露内部结构,也会让接口跟数据库紧密耦合。清晰的转换层可以保护边界。
页面字段不一定等于数据库字段。设计师可以先描述用户需要的信息,再与开发确定接口结构。
很多通用处理会在请求进入业务前后统一执行。
先看用户动作和业务风险,再理解技术为什么出现,以及它会怎样改变页面、状态和流程。
用户连续调用导出接口,系统需要验证登录、限制频率并记录请求链路。
把相同逻辑复制到每个 Controller 会造成遗漏和规则不一致。
Middleware 在请求进入业务逻辑前统一执行认证、Rate Limit,并生成 Trace ID。
当请求被限制或登录过期时,页面要显示剩余等待时间和重新登录入口。
日志、身份认证、请求追踪、限流、跨域和异常转换都可以通过 Middleware 或拦截器统一处理。这样每个 Controller 无需重复实现。
执行顺序很重要:先生成请求 ID,再记录日志,再验证身份,随后进入业务。响应返回时也可以统一补充 Header 或转换错误格式。
统一错误结构可以让前端建立稳定的 Toast、表单错误和重试逻辑。
系统需要明确什么输入合法、失败如何表达、重复请求如何处理。
先看用户动作和业务风险,再理解技术为什么出现,以及它会怎样改变页面、状态和流程。
支付按钮响应变慢,用户连续点击两次;客户端也可能因网络超时自动重试。
后端可能创建两笔支付单、重复扣款或重复发放权益。
客户端为一次业务操作生成幂等键,服务端记录处理结果;相同键再次到达时直接返回原结果。
按钮点击后立即进入处理中;超时提示“正在确认支付结果”,提供查询结果,避免直接引导再次支付。
运营上传客户名单,其中部分手机号和日期格式不合法。
缺少 Validation 会把脏数据写入系统;统一显示“导入失败”又无法帮助用户修复。
Schema 校验字段并生成结构化错误码,服务端返回错误行、字段和原因。
设计部分成功、错误报告下载、修复后重试和是否回滚全部数据。
Validation 检查必填、格式、范围和业务前置条件。错误应有稳定代码、可读消息和必要上下文,避免所有失败都返回同一个 500。
支付、创建订单等操作需要考虑重复点击和网络重试。幂等设计让同一个请求执行多次仍保持预期结果。
禁用按钮只能减少重复操作,后端仍需要处理重复请求和并发。
为“提交报销”画出 Controller、Service、Repository 的职责,并列出三种可能的业务错误。