Skip to content
格物致知
返回

全栈 UI 框架为什么不支持 OpenAPI?

摘要

本文从一次实验出发:为 Next.js + Zod 4 项目编写 OpenAPI 生成脚本,实验成功但结论为”不必要”。由此展开对全栈 UI 框架(Next.js / Nuxt / SvelteKit / Remix)与 API 框架(FastAPI / Hono / Express)在架构哲学上的对比分析,并探讨 AI 时代 API 契约的最优传递形式。

核心结论:全栈 UI 框架不支持 OpenAPI 是设计选择而非功能缺失;AI 消费者更偏好 Markdown 而非 JSON Schema。


1. 实验背景

1.1 问题

在 Next.js + Drizzle + Zod 4 的全栈 TypeScript 项目中,16 个 feature 模块各自维护 schemas.ts(Zod 定义)和 actions.ts(Server Actions)。项目需要:

  1. 给外部 AI 工具(V0/Stitch)提供 API 契约以生成 UI
  2. 在没有前端的情况下独立测试后端逻辑

FastAPI 项目中,这两个需求由自动生成的 openapi.json 同时满足。问题是:Next.js 能否复制这一能力?

1.2 实验过程

步骤方案结果
1@asteasolutions/zod-to-openapi失败 - 不支持 Zod 4
2zod-to-json-schema失败 - Zod 4 返回空对象
3Zod 4 原生 z.toJSONSchema() + 手动路由注册成功 - 50 paths, 41 schemas

最终脚本约 300 行,需要手动维护 import 列表和路由映射。

1.3 实验结论

脚本成功运行,但经评估后决定删除。原因见第 3 节。


2. 框架哲学对比

2.1 两类框架的定位

维度API 框架(FastAPI/Hono)全栈 UI 框架(Next.js/Nuxt)
核心抽象HTTP 请求/响应页面/组件
后端角色后端即产品后端是前端的实现细节
消费者不确定(多端/第三方)确定(自身前端)
OpenAPI自动生成(零配置)不支持
典型调用fetch("/api/users")createUser(data)

2.2 Server Actions 为什么没有 URL

Next.js Server Actions 的设计刻意移除了 HTTP 层:

这消除了前端调后端时的全部 HTTP 开销。当消费者就在同一个项目中时,HTTP 协议的所有契约机制(URL 设计、状态码语义、Content Negotiation)提供零价值。

2.3 全行业的共识

框架生态后端机制耦合度OpenAPI
Next.jsReactServer Actions最高
Nuxt.jsVueserver/api/ + Nitro
SvelteKitSvelteForm Actions
RemixReactLoaders/Actions
SolidStartSolidServer Functions

所有主流全栈 UI 框架均不支持 OpenAPI 自动生成。这不是巧合,而是同一设计原则的不同实现:当前端是唯一消费者时,HTTP 是不必要的抽象层。

2.4 两个阵营的适用场景

99% 的 Web 项目一辈子不需要对外 API。框架为多数场景优化是合理的工程选择。


3. OpenAPI 在 Next.js 中的成本分析

3.1 FastAPI 的零成本模型

@app.post("/api/users")
def create_user(data: UserCreate) -> User:
    ...
# openapi.json 自动包含这条路由,零额外代码

OpenAPI 有价值,因为它是路由定义的副产品,维护成本为零。

3.2 Next.js 的高成本模型

// 脚本中手写:
addCrud("/api/users", "Users", "User", "UserCreate", "UserUpdate");
addPath("post", "/api/users/me/change-password", "Users", "Change password", { body: "ChangePassword" });

这些路由在项目中不存在。每新增 feature 需要手动更新脚本。这不是自动化,而是新增了一份需要同步的代码

3.3 成本对比

维度FastAPINext.js (脚本)
路由映射自动手动(每个 feature)
Schema 转换自动需要注册
新增 feature零额外工作更新脚本
路由真实性真实端点虚构 URL
维护成本持续

结论:在 Next.js 中生成 openapi.json 的成本远高于收益。


4. AI 时代的契约传递

4.1 消费者视角验证

本次实验的关键转折点是直接询问 AI(openapi.json 的目标消费者):“你需要这个格式吗?”

AI 的评估:

4.2 推荐的契约格式

对 V0/Stitch 等外部 AI 工具,推荐 Markdown 表格:

## Users
| Field | Type | Required | Constraints |
|-------|------|----------|-------------|
| username | string | Y | 1-150 chars |
| email | string | Y | email format |
| password | string | Y | 8-128 chars |

生成方式:AI 扫描 src/features/*/schemas.ts,无需维护脚本。

4.3 完整的 UI 生成输入

仅有 API 契约不足以生成高质量 UI。完整输入应包括:

文档内容来源
UI.md页面布局、交互、列定义人工编写
API.md数据结构、操作、约束AI 从 schemas.ts 生成
Mock 数据示例 JSONAI 生成

UI.md 告诉 AI “画什么”,API.md 告诉 AI “数据长什么样”。


5. 对外 API 的预留方案

当项目未来需要对外 API(移动端/第三方集成)时,推荐方案是在 Next.js 中嵌入 Hono:

// app/api/[...route]/route.ts
const app = new Hono()
  .post("/users", async (c) => {
    const result = await createUser(await c.req.json());
    return c.json(result, 201);
  });

Hono 的 @hono/zod-openapi 可复用已有 Zod schema 自动生成 openapi.json。此时路由是真实的,OpenAPI 才有意义。

关键原则:需要时再加,不提前支付维护成本。


6. 结论

  1. 全栈 UI 框架不支持 OpenAPI 是设计选择,不是功能缺失。当前端是唯一消费者时,HTTP 契约机制无价值。
  2. 在 Next.js 中强行生成 openapi.json 成本高于收益:路由是虚构的,脚本需要持续维护。
  3. AI 消费者更偏好 Markdown 表格而非 JSON Schema:更紧凑、更易解析、更省 token。
  4. 对外 API 需求出现时,Hono 嵌入方案可在半天内完成,无需提前建设

分享文章:

上一篇
AI-to-AI Handoff Pipeline:规格驱动的全栈开发工作流
下一篇
OpenCode glob command failed 排查实录:当 AI Agent 帮你 Debug 自己的工具链