输入校验、错误处理与接口契约
真实请求不会永远正确。后端必须拒绝无效输入、给出稳定错误格式,并隐藏内部敏感细节。
- 接口失败时,调用方仍能可靠判断发生了什么。
- 类型、必填字段、长度与业务规则校验
- 为接口补齐至少五类错误响应,并从前端分别展示可理解提示。
- 完成 5.3「写出第一个后端接口」
FOUNDATION
必须理解
真实请求不会永远正确。后端必须拒绝无效输入、给出稳定错误格式,并隐藏内部敏感细节。
接口契约让前后端对字段和错误达成一致;输入校验保护业务边界;错误处理把失败变成可理解、可恢复的信息。三者共同决定联调是否稳定。
快递面单规定姓名、地址和电话格式;缺字段时工作人员不会把包裹随便寄出,而会指出哪项有问题。内部传送带故障也不会把机器细节写给顾客。
创建任务要求 title 为 1–80 个字符,成功返回 Task,校验失败返回字段错误,服务器异常返回通用信息并在日志保留细节。
类型、必填字段、长度与业务规则校验
校验会检查类型、长度、格式和业务规则。去掉标题首尾空格通常没问题,但不要在用户不知情时把内容改成另一种意思。
基础概念
输入校验是把外部数据与明确规则比较,包括类型、必填、长度、格式、取值范围和业务条件。只有全部满足后,数据才能进入核心逻辑。
进一步理解
类型与格式回答“长得对不对”,业务规则回答“在当前状态下允不允许”。例如标题是字符串仍可能过长,日期格式正确仍可能早于项目开始。
规范化可去除无意义差异,如首尾空格;但不能悄悄改变用户真实含义。校验错误应指向具体字段与可修复原因。
创建任务先确认 body 是对象、title 是 1–80 个字符,再确认同一项目没有违反唯一规则,最后才写数据库。
校验不是清洗一切输入,也不是安全的全部。权限、参数化查询和输出编码仍属于其他防线。
这一小节记住:在可信逻辑开始前,把数据形状与业务边界明确检查一遍。
400、401、403、404、409、500 的职责
接口契约就是前后端共同遵守的约定:用什么方法、发哪些字段、成功和失败分别长什么样。字段一改,两边都要知道。
基础概念
HTTP 400 表示请求无效,401 表示尚未认证,403 表示身份已知但无权操作,404 表示资源不存在,409 表示状态冲突,500 表示服务端意外失败。
进一步理解
状态码让调用方先判断失败类别,错误正文再给稳定代码、用户消息和可选字段细节。不同错误应保持语义一致,不能全部返回 200。
有时出于安全考虑,服务端会用 404 隐藏资源是否存在;这是明确策略,不是随意混用。500 响应给用户通用信息,内部日志保留请求标识与详细原因。
未登录创建任务返回 401;登录但编辑他人任务返回 403 或策略化 404;重复唯一标题返回 409;数据库异常返回 500。
401 不等于“权限不够”,403 也不等于“没登录”。状态码选择影响前端是引导登录、提示无权还是允许重试。
这一小节记住:用状态码表达失败类别,用稳定正文帮助调用方采取下一步。
稳定错误结构、日志和用户提示的差异
400 多半是请求本身有问题,401 和 403 与身份权限有关,404 是没找到资源,409 是冲突,500 则是服务端意外。给用户的错误要稳定,也别把堆栈和秘密直接吐出去。
基础概念
错误结构是程序之间的稳定契约,日志是维护者调查内部过程的证据,用户提示是面向当前任务的可理解说明。三者受众不同,信息量也不同。
进一步理解
响应可包含 `code`、`message`、`fieldErrors` 和 `requestId`;日志则记录异常类型、操作上下文和堆栈,但要脱敏。界面根据 code 决定聚焦字段或展示重试。
不要把原始数据库错误直接交给用户,也不要只在界面写“失败”。前者泄露内部,后者让用户无法恢复。请求 ID 可以安全地连接两类信息。
标题过长时响应指出 title 限制,界面把提示放到输入框旁;数据库故障只显示“暂时无法保存”,日志用 requestId 记录根因。
错误 message 适合人看,code 适合程序判断;把界面逻辑绑定完整中文句子会让文案调整破坏行为。
这一小节记住:同一次失败,为调用方、用户和维护者提供各自需要的信息。
AI COLLABORATION
AI 如何参与
让 AI 为接口列出正常、缺失、越界、重复、未授权和内部失败六类测试样例。
推荐协作顺序
- 1
把字段限制和错误结构告诉 AI,让它先列完整场景表。
- 2
逐条检查状态码、错误 code 和用户提示是否一致。
- 3
用边界输入实际调用,确认实现没有只照顾示例数据。
请为 POST /api/tasks 设计接口契约:title 必填且去空格后 1–80 字,重复标题允许。给出成功、空标题、超长标题、非法 JSON、服务器异常五种响应。错误格式统一为 { error: { code, message, field? } }。前端可以依据状态码和稳定错误 code 呈现反馈,服务端异常不暴露内部路径或堆栈。
人工检查清单
- 确认校验发生在服务端,客户端校验只是体验优化;状态码与含义一致。
- 要求 AI 为正常、缺失、越界、冲突、未授权和内部失败分别给出输入与预期响应。
- 亲自发送每类请求,确认状态码、错误结构、界面提示和日志内容相互对应且已脱敏。
COMMON TRAPS
常见误区
错误不是需要隐藏的失败,而是帮助你看清系统边界的证据。下面三类问题在 AI 辅助学习中最常出现。
只在输入框里做校验
- 你会看到
- 绕过网页直接调用 API,就能提交空标题或超长内容。
- 为什么发生
- 全部返回 200 会迫使调用方解析文案猜成功失败,缓存、监控和重试也无法利用协议语义。
- 怎样纠正
- 客户端校验改善体验,服务端校验才是可信边界。
错误信息泄露内部细节
- 你会看到
- 500 响应直接带数据库路径、堆栈或 SQL。
- 为什么发生
- 原始异常为开发者准备,可能包含 SQL、路径和堆栈;直接公开既难懂又扩大攻击信息。
- 怎样纠正
- 用户收到稳定且可行动的信息,详细错误只进受控日志。
错误格式每个接口都不同
- 你会看到
- 前端为每个请求写一套特殊判断。
- 为什么发生
- 只做类型校验会放过长度、状态和归属等业务非法值,数据仍会进入不一致状态。
- 怎样纠正
- 统一错误外形和 code 规则,再允许 message 针对场景变化。
HANDS-ON
动手任务
为接口补齐至少五类错误响应,并从前端分别展示可理解提示。
- 完成 5.3「写出第一个后端接口」
跟着做
- 01
为任务创建写出字段表和限制。
- 02
定义统一成功与错误 JSON。
- 03
在 Route Handler 中实现类型、空值与长度校验。
- 04
前端根据 field 显示输入框错误。
- 05
逐一调用五种场景并比较契约与实际响应。
接口失败时,调用方仍能可靠判断发生了什么。
加入幂等或冲突场景:相同请求重复提交时,决定产品应该创建两条还是返回冲突。
离开本课前,自问四件事
- 类型、格式和业务规则校验有什么不同?
- 400、401、403、404、409、500 各自表达什么?
- 稳定错误结构、用户提示和内部日志为何不能使用同一内容?
- 怎样让一条错误既能被前端处理,又能被维护者追踪?
确认完成后,会同步更新学习中心的课程学习进度。