小项目实战这个系列我之前写过一版今天这篇算第二篇。这几个月我一直在做内部工具的开发最深的感受是业务逻辑反而好写真正让人头疼的是接口设计和异常处理。接口一改前后端联调就乱异常没兜住半夜报警电话就会打过来。后来我试着把这两个环节交给 AI 来补齐——不是让 AI 直接写完整业务代码而是让它先出接口设计稿、再枚举异常场景、最后生成处理框架。这一轮试下来效率提升非常明显但也踩了不少坑所以把完整过程整理出来给正在做后端接口、全栈开发或独立项目的朋友参考。适合读这篇文章的人大概有几类一是接口文档总是被前端吐槽“字段又改了”的后端开发二是项目里异常处理写得比较随意全靠 try-catch 硬扛的同学三是想试试 AI 辅助编程但不知道从哪里切入的开发者。我尽量把提示词、对话思路、落地代码和排查经验都写清楚让你可以直接照着用。1. 项目实战背景与思路拆解1.1 为什么接口设计和异常处理最容易翻车接口设计表面上是“定义几个字段、约定几个状态码”但实际做起来牵扯的事情特别多。一个订单接口前端要看字段名、类型、嵌套结构后端要看校验规则、幂等策略、事务边界测试要看异常分支、状态码、错误信息格式。任何一方理解不一致联调阶段就开始互相甩锅。更麻烦的是异常处理很少有人在一开始就认真设计。大多数项目的常态是遇到参数错误就返回 400遇到业务错误就返回 500遇到数据库异常直接堆栈打到日志里。一次两次没问题等到接口被其他系统调用、或者对接小程序和 App 时才发现错误码不统一、请求 ID 没法串联、上游根本不知道该怎么处理失败。我用 AI 补齐这两个环节核心思路是把 AI 当成一个“随叫随到的资深同事”让它先输出方案我再做取舍。它不会因为嫌麻烦而漏掉边界也不会因为心情不好拒绝评审这对小项目来说非常实用。1.2 AI 能帮上哪些忙哪些忙帮不上先说 AI 擅长的部分。第一AI 很擅长从模糊需求里生成结构化内容。你给它一句话“需要一个创建订单的接口”它能补齐请求参数、响应结构、错误码、状态码而且格式比你随手写的 Notes 规整很多。第二AI 能快速枚举异常场景。人很容易漏掉“库存扣了但订单没创建成功”“重复点击导致创建了两单”这类情况AI 在提示词引导下反而能列出完整的清单。第三AI 可以保持风格统一。同一个项目里如果多个接口都由 AI 辅助生成字段命名、错误码格式、返回结构很容易保持一致。但 AI 也有明显帮不上忙的地方。它不了解你的业务全貌不知道哪些异常需要发送报警、哪些只需要记录日志它也不清楚你们团队的代码规范可能生成出跟现有代码风格完全不搭的类名和函数名。所以AI 适合做“初稿生成”和“查漏补缺”人工必须做“决策和把关”。这个定位摆正了后面基本不会翻大车。1.3 这次实战的准备工作为了把过程讲清楚我挑了一个最常见的场景创建订单接口。技术栈选了 FastAPI MySQL原因是上手快、适合小项目而且 AI 对 FastAPI 的掌握程度非常高。不管你是用 Spring Boot、Gin 还是 Express思路完全一样代码参考一下即可。准备工具方面我用了两个 AI 入口一个是网页版的对话助手用来做接口设计和异常场景的头脑风暴另一个是 IDE 里的 AI 编程插件用来在写代码时快速补全异常处理逻辑。实测下来两者各有优势网页版适合长上下文、多轮推演IDE 插件适合在真实代码文件里直接生成代码片段但上下文不够时容易“断片”。2. 用 AI 补齐接口设计的关键步骤2.1 提示词是第一步把模糊需求翻译成接口需求很多人用 AI 生成接口设计效果不好原因通常是提示词太简单。你只写“帮我设计一个订单接口”AI 只能给一个泛泛的 RESTful 模板跟你的业务完全对不上。正确做法是给足上下文让 AI 知道你有哪些约束和偏好。我常用的提示词模板是这样的你是一名资深后端工程师。请帮我设计一个“创建订单”接口。 技术约束 - 使用 FastAPI MySQL - 返回结构统一为 { code, message, data, request_id } - 接口风格遵循 RESTful - 需要支持幂等键防止重复下单 - 商品库存可能不足需要明确处理方式 请输出 1. 接口路径、请求方法、请求头、请求体 2. 正常响应的完整 JSON 示例 3. 所有可能出现的异常场景清单 4. 每个异常场景对应的 HTTP 状态码和业务 code 5. 接口实现的核心逻辑顺序这样写AI 会把你当成一个具体的项目角色而不是在回答一道概念题。关键词“技术约束”很重要它限制了 AI 的发挥空间“请输出”后面的结构要求让结果直接可用。2.2 字段、状态码、错误码的统一规范接口设计最怕前后端各玩各的。同一个错误前端只知道“失败了”后端却分不清是参数问题、权限问题还是下游服务挂了。所以我在跟 AI 对话时要求它先把错误码规范表做出来。以订单接口为例AI 给我的输出被我整理成了一张表业务 codeHTTP 状态码场景说明前端处理建议0200成功正常处理数据40001400缺少必填参数提示用户补全信息40002400商品数量非法提示用户修改数量40003422幂等键缺失或格式错误提示刷新重试或联系客服40301403用户无权操作跳转登录或提示无权限40401404商品不存在或已下架提示商品失效40901409重复提交订单提示订单已提交请勿重复操作50001500库存扣减失败提示稍后重试50002503下游支付/库存服务不可用提示网络繁忙稍后再试这张表直接扔给前端联调效率高很多。我后来发现让 AI 把“前端处理建议”也写出来是避免双方扯皮的关键。因为错误码本质上是给调用方看的不是给自己看的。2.3 让 AI 补全边界场景空值、并发、幂等接口设计里最容易漏的不是主流程而是边界。我让 AI 专门针对边界场景做了一轮补充它给出了几个我确实会忽略的点请求体里所有字段的边界字符串长度、数字范围、枚举值范围幂等键为空时怎么办是拒绝还是自动生成同一用户同时提交两个相同请求数据库层面如何防重商品库存刚好只剩 1 件两个请求同时扣减怎么保证不超卖上游库存服务超时是直接返回失败还是先创建订单再异步处理这几个问题如果靠自己列大概率要写到一半才想起来。用户跟你说“帮我设计接口”实际上他要的是一个能扛住真实流量和脏数据的接口。AI 在边界场景上的枚举能力比人脑稳定这是它最值钱的地方。3. 异常处理AI 最容易出彩也最容易翻车的地方3.1 先给 AI 明确异常分类异常处理如果一上来就让 AI“写个全局异常处理”它通常会给你一个堆满各种异常类的代码看着很专业实则过度设计。我的做法是先定义异常分类再让 AI 填充方案。我常用的分类很简单参数异常请求数据不合法通常由前端校验兜底但后端必须再校验一次业务异常符合参数规则但业务上不允许比如余额不足、库存不足、重复下单系统异常数据库连接失败、缓存故障、下游服务超时等第三方异常调外部 API 时的网络错误、鉴权失败、限流给 AI 的提示词会明确要求请基于以下异常分类设计订单接口的异常处理 1. 参数异常 - 返回 4xx业务 code 以 400 开头 2. 业务异常 - 返回 4xx业务 code 以 409 或 403 开头 3. 系统异常 - 返回 5xx业务 code 以 500 开头 4. 所有异常响应体保持统一格式 { code, message, data, request_id }加了分类之后AI 生成的异常处理结构清晰多了日志、告警、返回体都能各归其位。3.2 用 AI 生成异常处理框架和代码异常处理代码不需要每个接口写一遍用全局异常处理器更好。AI 很擅长生成这种重复性较高的模板代码。我用的是 FastAPI让 AI 生成的框架大概是这样的from fastapi import FastAPI, Request from fastapi.responses import JSONResponse class BizException(Exception): def __init__(self, code: int, message: str, http_status: int 400): self.code code self.message message self.http_status http_status class SystemException(Exception): def __init__(self, code: int, message: str, http_status: int 500): self.code code self.message message self.http_status http_status app FastAPI() app.exception_handler(BizException) async def biz_exception_handler(request: Request, exc: BizException): return JSONResponse( status_codeexc.http_status, content{ code: exc.code, message: exc.message, data: None, request_id: request.headers.get(X-Request-ID, ), }, ) app.exception_handler(SystemException) async def system_exception_handler(request: Request, exc: SystemException): return JSONResponse( status_codeexc.http_status, content{ code: exc.code, message: exc.message, data: None, request_id: request.headers.get(X-Request-ID, ), }, )这段代码本身不复杂但 AI 生成的“完整度”比我自己手写快。它还会主动提醒我request_id 应该从中间件生成而不是依赖前端传入。这属于很好的附加建议。3.3 人工 review 要盯这五个点AI 生成的异常处理框架我不会直接照搬。每次人工 review我重点看五个地方异常信息是否泄露内部细节。比如“MySQL connection failed”绝对不能直接返回给前端必须统一改成“服务繁忙”之类的文案详细错误只进日志。有没有把业务异常和系统异常混在一个类里。混用会导致前端无法判断到底要不要重试。日志是否打印了完整的堆栈和请求 ID。没有请求 ID 的日志排查问题时要命。是否所有入口都覆盖了。比如文件上传、定时任务、消息队列消费这些地方不一定走 HTTP 接口全局异常处理器管不到。异步任务里的异常是否单独处理。FastAPI 的 BackgroundTasks 抛了异常不会触发全局异常处理器必须自己 try-catch。3.4 让 AI 写异常处理的验证用例异常处理写完了怎么证明它有效我让 AI 帮我生成了订单接口异常路径的测试用例。AI 给出的用例包括def test_create_order_product_not_found(client): response client.post(/api/v1/orders, json{...}) assert response.status_code 404 assert response.json()[code] 40401 assert response.json()[message] 商品不存在或已下架这类用例的好处是能把异常场景变成可回归的检查点。下次谁改坏了跑一遍测试就知道。AI 生成测试用例时我会提示“覆盖所有错误码表里的场景”它就能自动补齐大部分。4. 实操过程一个订单接口的完整实战4.1 业务需求与约束定义我把这次实战的场景定义为用户提交订单商品库存扣减同时记录订单信息。项目约束如下用户 ID 和商品 ID 由调用方传入先做存在性校验每个请求必须带幂等键 Idempotency-Key防止重复下单扣减库存使用 Redis MySQL 双重校验避免超卖返回结构统一为 { code, message, data, request_id }所有异常都走全局异常处理器在实际项目中这些约束可能散落在需求文档、会议记录和代码注释里。我的做法是先人工整理成一段完整描述再丢给 AI。这一步很重要AI 不能替你做需求分析但能把你的需求分析翻译成合格的技术方案。4.2 第一轮对话生成接口设计初稿我把约束描述发给 AI要求输出接口文档。AI 给的结果非常规整关键内容如下POST /api/v1/orders 请求头 - Content-Type: application/json - X-Request-ID: 可选建议由网关生成 - Idempotency-Key: 必填用于幂等控制 请求体 { user_id: user_123, product_id: product_456, quantity: 2, coupon_id: null } 响应体成功 { code: 0, message: success, data: { order_id: order_789, status: CREATED, total_amount: 199.00 }, request_id: req_abc123 }看到这个初稿我会重点检查几个地方幂等键到底放 header 还是 bodyAI 放 header这个可以。但 AI 没有定义幂等键过期时间也没有说明重复请求时返回什么——这些需要第二轮对话补齐。第一次生成的结果通常只能当草稿不能直接用于开发。4.3 第二轮对话补齐异常处理接着我让 AI 基于错误码表补齐异常处理策略。AI 输出的内容中最有价值的是“重复提交”的处理方案当 Idempotency-Key 已存在且对应订单状态为“已创建”时接口应返回第一次创建的订单数据HTTP 状态码可以是 200也可以返回 409。具体取决于业务方是否需要区分“新创建”和“重复请求”。如果前端只关心订单是否创建成功建议直接返回 200 和原始订单数据。这个建议让我少踩了一个大坑。很多新人在做幂等的时候直接返回“重复请求”错误结果用户在页面上多点了一次提交看到的不是订单成功而是一条错误提示。AI 能从调用方角度分析这点很加分。4.4 落地成代码并验证接口设计和异常处理确定后我让 IDE 插件基于上述设计生成核心代码。关键逻辑长这样app.post(/api/v1/orders) async def create_order(request: Request, body: OrderCreateRequest): request_id request.headers.get(X-Request-ID, ) idempotency_key request.headers.get(Idempotency-Key, ) if not idempotency_key: raise BizException(code40003, message幂等键缺失, http_status422) existed_order await order_service.get_by_idempotency_key(idempotency_key) if existed_order: return {code: 0, message: success, data: existed_order, request_id: request_id} user await user_service.get_by_id(body.user_id) if not user: raise BizException(code40401, message用户不存在, http_status404) product await product_service.get_by_id(body.product_id) if not product or product.status ! ON_SALE: raise BizException(code40401, message商品不存在或已下架, http_status404) if body.quantity 0 or body.quantity product.stock: raise BizException(code40002, message商品数量非法, http_status400) try: order await order_service.create_order(user, product, body.quantity, idempotency_key) except InventoryShortageException: raise BizException(code50001, message库存扣减失败, http_status500) except Exception as e: logger.error(fcreate_order failed request_id{request_id}, exc_infoe) raise SystemException(code50002, message服务繁忙, http_status503) return {code: 0, message: success, data: order, request_id: request_id}这里有个细节库存不足在业务上通常不是服务器错误但“扣减库存失败”也可能代表系统数据不一致所以 code 用 50001、HTTP 状态码用 500。具体怎么定得看业务方怎么理解。AI 生成代码时会给你默认值但最终状态码含义必须人工确认。验证时我用 curl 模拟了四种情况正常创建订单不带幂等键直接请求返回 422 和 code 40003商品 ID 不存在返回 404 和 code 40401带相同幂等键重复请求第二次返回第一次的订单数据全部符合预期。整个流程从需求到代码验证用时比我以前手写至少省了半天。5. 常见问题与排查技巧实录5.1 AI 生成接口时的“幻觉”和纠偏方法AI 有一个很典型的问题它会一本正经地生成一个看起来合理但根本不存在的字段或接口。比如我让它设计订单接口它可能会自己加一个payment_method但项目里根本没有支付模块。这种幻觉在小项目里尤其容易混过去因为看起来太合理了。纠偏方法就一个逐字段 review。把 AI 输出的所有字段、状态码、方法名跟真实业务对照一遍凡是业务里不存在的概念要么删除要么标注“未确认”。千万不要因为 AI 给你补齐了就觉得它一定对。5.2 异常处理过度设计的判断标准AI 还容易把异常处理写得过度复杂。它会给你设计一个ExceptionHandlerFactory再配一堆AbstractException、ErrorCodeEnum小项目根本用不上。判断标准很简单异常分类是否超过三到四大类是不是每个异常都要走一个单独的处理器代码里是否出现了大量“未来可能用到”的抽象层如果答案都是“是”建议让 AI 简化。小项目的异常处理核心就两件事把状态码和错误消息正确返回给调用方把内部错误细节留到日志里。其他都是额外负担。5.3 让 AI 输出更稳定的几个小技巧我试了很多种提示词写法总结下来这四个技巧对输出稳定性帮助最大在提示词里给一个“坏例子”和“好例子”。AI 看过样例后输出风格会明显向样例靠拢。要求 AI 分步骤输出不要一次给完整代码。先出接口文档再出异常场景最后出代码每个阶段可以单独审阅。每次对话只聚焦一个目标。接口设计和异常处理虽然相关但最好分两轮对话否则 AI 容易把两者揉在一起重点不突出。如果 AI 给的结果不满意不要直接放弃而是追问“请基于你的方案补充我遗漏的场景”。多轮追问的效果比重新生成好得多。5.4 问题排查速查表我在实战中总结了一张排查清单每次 AI 生成的内容有问题我都会按这个顺序检查问题现象排查方向处理建议接口字段缺失业务上下文是否给全补充用户、商品、订单字段说明错误码不统一有没有先定错误码规范先要求 AI 输出错误码表异常处理全是 try-catch没有定义全局异常策略要求 AI 设计全局异常处理器AI 生成了不存在的模块上下文里没有明确模块边界限制技术栈和业务范围幂等逻辑太弱没有强调重复提交场景单独围绕幂等做一轮追问代码与现有风格不一致没有给出代码风格样例在提示词中贴一段现有代码这张表我直接放在项目笔记里每次用 AI 辅助设计接口都会翻出来对照。我个人在实际操作中的体会是AI 补齐接口设计和异常处理最高效的用法不是当“代码生成器”而是当“设计评审脑暴对象”。它可以帮你把脑子里模糊的想法变成一个看得见、摸得着的初稿也能在边界场景上查漏补缺。但最后的责任始终在自己身上——接口字段合不合理异常返回会不会误导调用方这些都需要人工亲自定夺。如果你也准备在小项目里用 AI 做类似的事情建议先从本周正在写的接口开始把提示词、错误码表、异常框架跑一遍然后再决定哪些部分可以放心交给 AI。等你用顺手了会发现真正省下来的不是敲代码的时间而是反复沟通需求和排查线上异常的时间。
阅读完成 · 觉得有帮助?