title: Claude Code 前后端联调实战:让 Claude 帮你打通 REST API
date: 2026-07-07
category: AI 开发工具
tags: [Claude Code, REST API, 前后端联调, Axios, 跨域]

Claude Code 前后端联调实战:让 Claude 帮你打通 REST API

前端页面写得再漂亮,连不上后端就是一张空壳。本篇教你如何用 Claude 同时搞定前端请求和后端接口,让前后端联调变得像"填空"一样简单。

前言

BS 架构开发中,最折磨人的环节往往是前后端联调

  • 前端传的字段名和后端接收的不一致
  • 分页参数前端叫 pageNum,后端叫 page
  • 日期格式前端传的是时间戳,后端要的是 yyyy-MM-dd
  • 跨域报错、CORS 配置不对、Token 传递方式不一致

如果前后端都是你一个人开发,Claude Code 可以帮你一把梭——同时操作前端和后端代码,确保接口契约完全对齐。

一、先定义 API 契约

1.1 让 Claude 生成接口文档

在动手写代码之前,先让 Claude 帮你梳理接口。对 Claude 说:

我们是一个用户管理系统,需要以下功能:
- 用户 CRUD(增删改查 + 分页 + 搜索)
- 角色管理(列表 + 权限分配)
- 部门管理(树形结构 + 增删改)

请帮我整理一份 RESTful API 清单,包含路径、方法、请求参数、响应格式。

Claude 会输出一份结构化的接口清单:

功能方法路径请求体响应
用户列表GET/api/userspageNum, pageSize, keyword, status{ code, message, data: { list, total } }
创建用户POST/api/usersusername, name, email, role, status{ code, message, data: userId }
更新用户PUT/api/users/{id}name, email, role, status{ code, message }
删除用户DELETE/api/users/{id}{ code, message }
切换状态PATCH/api/users/{id}/statusstatus{ code, message }
部门树GET/api/departments/tree{ code, message, data: Dept[] }

关键:这份清单就是前后端的"合同"。双方都按照这个契约开发,联调时几乎不会出问题。

1.2 让 Claude 生成 TypeScript 类型

基于上面的 API 清单,生成对应的 TypeScript 接口定义

Claude 会生成 src/api/types.ts

// 请求参数类型
export interface UserListQuery {
  pageNum: number
  pageSize: number
  keyword?: string
  status?: 'active' | 'inactive'
}

export interface CreateUserPayload {
  username: string
  name: string
  email: string
  role: 'admin' | 'editor' | 'viewer'
  status: 'active' | 'inactive'
}

export interface UpdateUserPayload {
  name?: string
  email?: string
  role?: 'admin' | 'editor' | 'viewer'
  status?: 'active' | 'inactive'
}

// 响应类型
export interface User {
  id: number
  username: string
  name: string
  email: string
  role: 'admin' | 'editor' | 'viewer'
  status: 'active' | 'inactive'
  departmentId: number
  createTime: string
  updateTime: string
}

export interface DeptNode {
  id: number
  name: string
  children?: DeptNode[]
}

二、用 Claude 搭建 API 模块

不要直接在组件里写 get('/api/users')。让 Claude 帮你创建一个专门的 API 层:

在 src/api/ 目录下创建一个 user.ts,封装所有用户相关的 API 调用。
使用前面定义的 http 模块的 get/post/put/delete 方法。
每个函数都要有完整的 TypeScript 类型注解。

生成的 src/api/user.ts

import { get, post, put, del } from '@/utils/http'
import type { User, UserListQuery, PageResult, CreateUserPayload, UpdateUserPayload } from '@/api/types'

/**
 * 获取用户列表
 */
export function getUserList(params: UserListQuery) {
  return get<PageResult<User>>('/users', { params })
}

/**
 * 创建用户
 */
export function createUser(data: CreateUserPayload) {
  return post<number>('/users', data)
}

/**
 * 更新用户
 */
export function updateUser(id: number, data: UpdateUserPayload) {
  return put<void>(`/users/${id}`, data)
}

/**
 * 删除用户
 */
export function deleteUser(id: number) {
  return del<void>(`/users/${id}`)
}

/**
 * 切换用户状态
 */
export function toggleUserStatus(id: number, status: 'active' | 'inactive') {
  return patch<void>(`/users/${id}/status`, { status })
}

好处:组件里只需要 import { getUserList } from '@/api/user',业务逻辑和 API 调用完全分离。

三、Vite 代理配置解决跨域

开发环境中,前端运行在 localhost:5173,后端运行在 localhost:8080,跨域是必然的。

让 Claude 帮你配置 Vite 代理:

配置 Vite 开发服务器,将所有 /api 开头的请求代理到 http://localhost:8080,
需要修改请求头中的 Host,并且去掉 URL 中的 /api 前缀。

Claude 会修改 vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src'),
    },
  },
  server: {
    port: 5173,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
})

原理:请求 GET /api/users?pageNum=1 → Vite 代理 → GET http://localhost:8080/users?pageNum=1。对浏览器来说没有跨域,对后端来说请求直接来自本地。

四、联调时的常见问题与 Claude 的解决方案

4.1 字段名不一致

现象:前端传 pageNum,后端收不到。

排查:让 Claude 检查前后端的参数定义。

检查一下前端的分页参数和后端 Controller 的@RequestParam 是否一致

Claude 会对比前端 UserListQuery 类型和后端 Controller 方法签名,发现后端用的是 @RequestParam(defaultValue = "1") Integer page,而前端传的是 pageNum

修复:统一改为 pageNum,或者在前端映射层做转换。

4.2 日期格式问题

现象:前端传的日期是 "2026-07-07T03:30:00.000Z",后端期望 "2026-07-07"

解决

在 Axios 请求拦截器中,把所有日期类型的参数统一格式化为 yyyy-MM-dd

Claude 会在 http.ts 的请求拦截器中添加日期格式化逻辑,或者在 API 调用层做预处理。

4.3 Token 传递方式不一致

现象:后端期望 Authorization: Bearer <token>,前端传的是 token: <token>

解决

确认前后端的 Token 传递方式,确保前端请求头中使用 Authorization: Bearer xxx

Claude 会检查前端拦截器和后端拦截器的配置,确保一致。

4.4 分页数据结构不一致

现象:前端期望 { list: [...], total: 100 },后端返回 { records: [...], total: 100 }

解决

后端返回的分页数据结构是 { records, total },前端期望的是 { list, total },
在前端响应拦截器中做字段映射,把 records 改为 list

Claude 会在响应拦截器中添加字段转换逻辑。

4.5 文件上传/下载

现象:导出功能返回的文件流被解析成了 JSON,报解析错误。

解决

导出接口需要返回文件流而不是 JSON,在请求中设置 responseType: 'blob'

Claude 会在 getUserList 之外新建 exportUsers 函数,单独设置 responseType: 'blob',并在组件中用 Blob + URL.createObjectURL 触发下载。

五、Mock 数据——后端还没写好怎么办?

实际开发中,前后端经常不是同步完成的。让 Claude 帮你生成 Mock 数据:

后端还没准备好,先用 Mock 数据让前端跑起来。
在 src/mock/ 目录下创建一个 userMock.js,用 Mock.js 模拟用户列表 API。
返回 50 条随机用户数据,分页结构符合 PageResult 类型。

Claude 会生成完整的 Mock 模块,前端先连 Mock,后端就绪后只需改一行 import 即可切换。

六、用 Claude 做接口测试

联调完成后,让 Claude 帮你写接口测试用例,确保每个接口都能正常工作:

为 user API 写一组 Postman / curl 测试用例,覆盖正常请求和异常场景:
- 正常获取列表
- 搜索过滤
- 创建用户(含参数校验失败)
- 更新不存在的用户
- Token 过期

Claude 会生成一组可直接在终端执行的 curl 命令,或者一个 Postman Collection JSON 文件。

七、这一章的核心心得

  1. 先契约后开发——让 Claude 先生成接口清单和类型定义,前后端照着契约各自开发
  2. API 层与组件层分离——所有 HTTP 调用集中在 src/api/ 目录,组件只管业务逻辑
  3. Vite 代理是跨域的最优解——开发环境用 proxy,生产环境由 Nginx 反向代理解决
  4. 联调出错时让 Claude 做"翻译官"——它能在前后端代码间快速定位不一致的地方
  5. Mock 数据保证开发不等待——后端没好?Claude 帮你造数据先跑起来

八、下一步

API 联调打通后,页面数据已经能正常显示了。但对于复杂业务——比如用户和角色的多对多关系、部门树的展开收起、多 Tab 页面的状态共享——单纯靠组件内的 ref/reactive 已经不够用了。下一篇我们将学习用 Pinia 做全局状态管理,让 Claude 帮你搭建可维护的状态架构。


系列目录:

  1. 初识 Claude Code:用自然语言打造第一个 Web 页面 ← 上一篇
  2. 页面级交互实战:表单、弹窗与数据联动 ← 上一篇
  3. 前后端联调:让 Claude 帮你打通 REST API ← 本篇
  4. 状态管理:Pinia 与复杂业务逻辑(待写)
  5. 深入 Claude Code:Agent 多智能体协作(待写)
  6. Claude 驱动的后端开发:Spring Boot + 数据库(待写)
  7. 工程化进阶:代码审查、调试与性能优化(待写)
  8. 高级玩法:工作流编排与团队协作(待写)
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐