⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议
Skip to content

第七章:后端API开发

序言

界面有了,数据库也准备好了。你点击"提交"按钮,数据应该存入数据库——但前端和数据库之间还缺一座桥。

这座桥就是 API(应用程序接口)。前端通过 HTTP 请求告诉后端用户想要什么,后端处理后返回响应。


什么是后端

后端是运行在服务器上的代码,负责处理前端发来的请求、与数据库交互、执行业务逻辑。

职责
前端展示界面、收集用户输入、发送 HTTP 请求
API接收请求、验证参数、调用数据库、返回响应
数据库存储和检索数据

前端不能直接访问数据库——那样会暴露所有数据,也无法做权限控制。API 是数据库的守门员,所有数据操作必须通过它。


什么是 API Route

Route(路由) 是 Web 开发中的核心概念,指 URL 路径与处理代码之间的对应关系。用户访问某个 URL 时,路由系统决定调用哪段代码来响应。

API Route 是 Next.js 中定义 API 接口的方式。你创建一个文件,它就变成了一个可以访问的接口。

具体来说,在 app/api/ 目录下创建 route.ts 文件,就会自动生成对应的 URL 路径。比如创建 app/api/posts/route.ts,就会产生 /api/posts 这个接口。

导出处理函数

route.ts 文件中,你导出对应 HTTP 方法的函数。比如导出 GET 函数来处理 GET 请求,导出 POST 函数来处理 POST 请求。

Next.js 会根据请求方法自动调用对应的函数。如果同时导出了 GETPOST,同一个 URL 就可以同时支持获取和创建两种操作。

动态路由参数

如果路径中包含动态部分,比如 /api/posts/123 中的 123,该怎么获取呢?你在文件名中用方括号表示动态段,比如 [id],然后就可以从 params 中提取出这个 123

版本变化快,让 AI 查文档

Next.js 版本迭代快,API 可能有变化。让 AI 用 Context7 查询最新文档,确保生成的代码符合当前版本。


RESTful 设计风格

RESTful 是一种 API 设计风格,核心思想是用 URL 表示资源,用 HTTP 方法表示操作

比如 /api/posts 这个 URL,用 GET 方法表示获取文章列表,用 POST 方法表示创建新文章。/api/posts/123 用 GET 方法获取 id=123 的文章,用 DELETE 方法删除它。

这样设计的好处是"看到路径就知道做什么",前端开发者不用猜每个接口的用法。


参数的三种来源

后端接收参数有三种方式,需要区分清楚:

路径参数——比如 /posts/123 中的 123,嵌入在 URL 路径中,通过 params 获取(需要 await)。

查询参数——比如 /posts?page=1 中的 page=1,跟在 URL 问号后面,通过 searchParams 获取。

请求 Body——POST 请求中携带的 JSON 数据,通过 request.json() 获取。

这三种方式各有使用场景:路径参数用于标识单个资源,查询参数用于过滤或分页,Body 用于传递复杂的数据结构。


参数校验与错误处理

老师傅严肃地提醒你:永远不要信任前端发来的数据。用户可以通过浏览器开发者工具伪造任何请求,甚至直接调用 API。

你审查代码时发现,AI 生成的接口没有任何参数校验——任何人都可以传空标题、负数年龄。你让 AI 加上 Zod 库的类型安全校验,校验失败返回 400 错误。

Zod 的使用方式是:先定义一个 schema,描述数据应该长什么样(比如标题必须是字符串、长度在 1-100 之间),然后在处理请求前用这个 schema 去验证。如果验证失败,就返回 400 错误给前端。

Zod 的好处是类型安全 + 校验合一,TypeScript 类型会自动推导,不用写两遍。


错误响应格式

统一的错误响应格式让前端更容易处理。

约定一个格式:成功时返回 { success: true, data: ... },失败时返回 { success: false, error: { message: "...", code: "..." } }

这样前端处理起来就很简单——先看 success 字段,为 true 就取 data,为 false 就显示 error.message


连接数据库

API 的真正价值在于它是数据库的守门员。前端不能直接访问数据库,必须通过 API 作为中介。

审查时你发现几个常见问题:AI 返回了用户密码字段(安全风险)、忘记处理数据库错误导致接口崩溃、环境变量没配置导致连接失败。

正确的做法是:查询数据库前先确保环境变量配置正确;查询时用 try-catch 包裹,处理数据库错误;返回数据前过滤掉密码等敏感字段;资源不存在时返回 404,而不是让接口崩溃。

数据库操作使用 Drizzle ORM,它提供了类型安全的查询 API,可以用链式调用的方式构建查询,比如 db.query.posts.findFirst({ where: eq(posts.id, id) })

完整 CRUD 示例

数据库操作的完整 CRUD 示例(增删改查),请让 AI 根据你的数据表结构生成。告诉它:请根据我的数据表结构,生成完整的 CRUD API 代码,使用 Drizzle ORM。


真正容易踩的坑

审查过程中,这些坑值得注意:

  • 动态路由参数paramsPromise,使用前必须 await
  • CORS 配置:如果前端和后端不同域,需要正确配置 CORS 头
  • 缓存策略:Next.js 的 fetch 默认会缓存,可能导致数据过期
  • 环境变量:数据库连接字符串等敏感信息要放在 .env.local,不能提交到代码仓库
  • revalidatePath:修改数据后要调用 revalidatePath 清除缓存,否则前端看不到更新
  • 版本差异:Next.js 版本更新快,旧教程的代码可能不适用

让 AI 反复检查

Next.js 版本迭代快,AI 训练数据可能过时。让 AI 用 Context7 查询最新文档,反复验证:检查 params 的类型、函数签名、返回值格式是否符合当前版本规范。


你的工作

整个过程中你不需要手写每个接口。你只需要告诉 AI 需求,它会生成完整的代码。你的工作是审查和验证

  1. 代码能跑吗? —— 本地测试一下
  2. 边界情况处理了吗? —— 空值、错误、超时
  3. 安全吗? —— 参数校验、敏感数据过滤
  4. 性能行吗? —— N+1 查询、缓存策略

学会了这些,你就能放心地让 AI 帮你写后端了。