前后端分离开发,别再"傻等"后端接口了——聊聊前端接口工程

前后端分离开发,别再"傻等"后端接口了------聊聊前端接口工程

有个朋友之前做小组作业,跟我吐槽:"后端同学接口还没写,我前端页面都画好了,结果只能干坐着等接口,一等等三天。"

我问他:你为什么要等?

他说:没接口,我拿不到数据,页面就是死的啊。

这就是今天想聊的话题------前后端分离之后,前端到底怎么做到不等后端,也能把整个 App 独立写完。

一、先搞清楚一个问题:前后端分离,分离了吗?

现在几乎没人会把 HTML、CSS、JS 和后端代码写在一起了。前端是独立工程,后端也是独立工程,各自 npm run dev 起一个服务,看起来很"分离"。

但只要你真的写过联调,就会发现一个尴尬的事实:

前后端之间,还留着一根"脐带"------/api 接口。

前端要渲染数据,得调后端的接口;后端接口没写好,前端就"断粮"了。

更气人的是:前端画界面可能只需要半天,但等后端接口可能要等好几天。 这半天和好几天之间,前端就变成了"摸鱼时间"。

那能不能把这根脐带也剪断?

能。办法就是------前端自己做一层"接口工程",先用假数据(mock)把页面跑起来,等后端真接口好了,再"一键切换"过去。

这就是这个项目 todos-fullstack 想讲清楚的事。

二、前端独立开发的"三辆马车" + 一个关键补充

先看一个独立的前端应用,到底需要哪些东西。我的理解是"三辆马车":

马车 作用 对应技术
组件 响应式渲染界面 React 19
路由 页面级别的跳转 react-router-dom 7
状态管理 全局数据的"银行" zustand 5

这三辆马车配齐了,前端就能独立跑起来。

但很多人漏掉了第四样东西------数据从哪来?

组件负责"画",路由负责"去哪",状态管理负责"存",那数据接口谁来管?

答案是:前端接口工程(API 工程) 。它不归 react-router 管,它是自己独立的一层。这就是这个项目里 src/api/ 目录存在的意义。

bash 复制代码
todos-fullstack/
├── backend/            # 后端:node + koa + mysql(真正的接口)
└── frontend/todos/
    ├── mock/           # 前端造的"假接口"
    ├── src/
    │   ├── api/        # ⭐ 前端接口工程
    │   │   ├── config.js   # axios 配置(baseURL 一键切换)
    │   │   └── todos.js    # 每个模块一个接口文件
    │   ├── pages/      # 页面级路由
    │   ├── components/ # 通用组件
    │   └── App.jsx
    └── vite.config.js

三、核心:用 mock 把"假接口"接上

思路很简单:后端没给真接口,前端就自己伪造一个同路径的假接口。

这里用的是 vite-plugin-mock。在 vite.config.js 里加一段配置:

js 复制代码
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { viteMockServe } from 'vite-plugin-mock'

export default defineConfig({
  plugins: [
    react(),
    viteMockServe({
      mockPath: './mock',   // mock 文件放哪
      localEnabled: true,   // 本地开发开启
    }),
  ],
})

然后在 mock/ 目录写假接口。注意:路径要和后端约定的一致 ,这里就是 /api/todos

js 复制代码
// mock/todos.js
export default [
  {
    url: '/api/todos',
    method: 'GET',
    timeout: 2000, // 故意模拟网络延迟
    response: () => {
      return {
        code: 0, // 0 表示成功
        todos: [
          { id: 1, title: '学习前端接口工程', completed: true },
          { id: 2, title: '看龙餐馆', completed: false },
        ],
      }
    },
  },
]

现在你在浏览器访问 http://localhost:5173/api/todos,就能拿到这段假 JSON 了。前端"有粮"了。

四、前端接口工程:把"请求"统一管起来

光有 mock 还不够。如果每个组件里都直接 fetch('/api/todos'),等后端接口地址一变,你就要全局搜索替换,灾难。

所以要把请求收口到一层 。这就是 api/ 目录的职责。

第一步:配置 axios 实例,baseURL 统一管理。

js 复制代码
// src/api/config.js
import axios from 'axios'

const instance = axios.create({
  baseURL: '/api', // 开发环境:走前端 mock
  // baseURL: 'http://localhost:3000', // 上线:改成后端真实地址
  timeout: 5000,
})

export default instance

看到这行注释了吗?这就是"一键切换"的灵魂:

  • 开发阶段 baseURL: '/api' → 请求走 Vite 的 mock 插件
  • 联调/上线时 → 改成 http://localhost:3000(后端 Koa 地址)

只改一行,全局生效。 再也不用每个请求去改地址。

第二步:每个业务模块一个接口文件。

js 复制代码
// src/api/todos.js
import axios from './config'

export const getTodos = async () => {
  const res = await axios.get('/todos')
  return res.data
}

这样组件里调用就非常干净,只关心业务,不关心地址:

jsx 复制代码
// src/pages/Todos.jsx
import { useState, useEffect } from 'react'
import { getTodos } from '../api/todos'

function Todos() {
  const [todos, setTodos] = useState([])

  useEffect(() => {
    (async () => {
      const data = await getTodos()
      setTodos(data) // ⚠️ 注意:这里 data 是响应体 { code, todos },实际要取 data.todos
    })()
  }, [])

  return <>Todos</>
}

顺便说个容易被忽略的细节:mock 返回的结构是 { code: 0, todos: [...] },所以 data 其实是整个响应体,不是数组。约定好响应结构(比如统一 code 字段)后,前端取值的地方要记得 data.todos 这是很多新手联调时会懵一下的小坑。

五、前后端切换,到底切的是啥?

现在回头看整个流程,就很清楚了:

text 复制代码
开发阶段(前端独立)
  组件 → getTodos() → axios baseURL=/api → vite-plugin-mock 拦截 → 返回假数据

联调/上线阶段(切后端)
  组件 → getTodos() → axios baseURL=http://localhost:3000 → Koa 真接口 → 返回真数据

组件代码一行不用改。 变的只是 config.js 里的一行 baseURL

这就是"前端接口工程"的价值:把「数据从哪来」这个易变的东西,和「界面长什么样」这个稳定的东西,彻底解耦。

六、总结

回到最开始那个问题:前端为什么要傻等后端?

答案是不用等。你可以:

  1. 用 mock 伪造假接口,先让页面跑起来;
  2. api/ 目录统一管理请求 ,别让 fetch 散落在各个组件里;
  3. baseURL 一键切换,后端好了切过去,全程只改一行。

这背后其实是一种心态的转变:前后端分离,不光是"文件分开",更是"进度解耦"。 前端不是后端的附庸,前端自己也能是一套完整的工程。


写在最后

这篇文章里的 todos-fullstack 是个教学脚手架,重点是讲清楚「前端接口工程」这个思路,所以 Zustand 这辆"马车"目前只上了车、还没真正开动(状态还停在组件内的 useState)。如果你感兴趣,下一篇我可以接着聊聊:当 todo 列表复杂起来,怎么把状态从 useState 搬到 Zustand 这个"银行"里。

你在做前后端分离时,是"傻等接口"派,还是"mock 先行"派?

欢迎在评论区聊聊你的经历,特别是被联调卡过进度的血泪史 👇

相关推荐
前端_刘师兄1 小时前
前端开发工程师转FAE工程师路线规划
前端
禁止摆烂_才浅1 小时前
前端 AI 面试题
前端·面试·ai编程
程序员老赵1 小时前
Docker 部署 ZLMediaKit:轻松搭建高性能流媒体服务平台
前端·javascript·后端
Liora_Yvonne1 小时前
为什么每次发版,总有用户看到白屏?
前端
风月说与山鬼1 小时前
四、浏览器存储
前端·vue.js
hunterandroid1 小时前
[Android 从零到一] ViewPager2 与 Fragment 生命周期协同:从预加载到状态一致性
android·前端
liuxiaocheng1 小时前
上下文工程:LangChain 怎么组织「喂给模型的东西」
前端·后端
breeze jiang1 小时前
CSS 三栏布局怎么写:Flex、Grid 完整方案与 BFC 区别
前端·css
SendTomo1 小时前
SendTomo稳定传输三大核心策略
javascript·网络协议·webrtc·html5·p2p