Midway 函数式开发前端集成:React/Vue 项目与函数式服务端 API 的零断点桥接实战

📅 发布时间:2026/10/9 3:16:24
Midway 函数式开发前端集成:React/Vue 项目与函数式服务端 API 的零断点桥接实战
后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载导读本文基于 Midway 官方指南 前端集成给出一条可直接落地的路线讲解如何把已有的 React/Vue 前端项目与函数式 MidwaydefineApi定义的 API无缝接起来前端通过类型安全的createClient客户端直接调用服务端 API 定义Vite 开发服务器同时托管 Midway 业务接口midwayjs/web-bridge的构建插件负责把服务端 API 定义翻译成浏览器可安全加载的路由契约。读完本文你将掌握依赖安装与目录组织、defineApi zod 的服务端 API 定义、前端 client 的创建与调用、Vite/Rspack 桥接配置、函数式中间件的路由级与模块级挂载方式以及自定义目录时的注意事项。1. 安装依赖在前端项目中补齐 Midway 依赖如果你已经是一个前端项目有package.json、Vite、React/Vue不需要重建工程只需补齐 Midway 相关依赖。核心包分为四类职责midwayjs/core函数式 Midway 的运行时核心提供defineApi等函数式 API 能力midwayjs/web-bridge前后端桥接层提供 Vite/Rspack 构建插件与底层的createClient实现midwayjs/mock开发期把 Midway 应用挂到 Vite 上的devPluginmidwayjs/react/midwayjs/vue对应框架的createClient导出内部复用midwayjs/web-bridgezod函数式 API 的运行时 schema 校验与类型推导。React 项目$ npm i midwayjs/core midwayjs/web-bridge midwayjs/mock midwayjs/react zodVue 项目$ npm i midwayjs/core midwayjs/web-bridge midwayjs/mock midwayjs/vue zod2. 准备目录一个项目内同时容纳前端与函数式服务端推荐的项目结构如下前端与函数式服务端共存于同一个src下通过src/web浏览器代码与src/server服务端 API 定义做物理隔离. ├── package.json # 项目脚本与依赖 ├── vite.config.ts # Vite 配置含 devPlugin/apiPlugin ├── src │ ├── main.tsx / main.ts # React/Vue 入口 │ ├── web │ │ ├── app.tsx / app.vue # 前端根组件 │ │ └── api │ │ └── client.ts # 前端 API 客户端 │ └── server │ ├── index.ts # Midway 服务端入口也可命名为 configuration.ts │ └── api │ └── user.api.ts # 服务端 API 定义 └── tsconfig.json # TypeScript 配置仓库中的 react-functional-api 示例 正是按此布局组织src/server/api/user.api.ts定义服务端 APIsrc/web/api/client.ts创建前端客户端src/main.tsx作为 React 入口。注意src/web与src/server是推荐约定而非强制详见文末第 10 节自定义目录说明。3. 定义服务端 APIdefineApi zod 的输入输出契约在src/server/api/user.api.ts中用函数式 API 语法定义路由、输入校验与输出类型// src/server/api/user.api.ts import { defineApi } from midwayjs/core/functional; import { z } from zod; export const userApi defineApi(/users, api ({ getUser: api .get(/:id) .input({ params: z.object({ id: z.string() }), }) .output( z.object({ id: z.string(), name: z.string(), }) ) .handle(async ({ input }) { return { id: input.params.id, name: harry, }; }), }));这里有两点值得展开说明原文明确强调了这两个效果input(...)是运行时校验器它不只声明类型还会在请求真正到达handle之前对params路径参数、query查询参数、body请求体、headers请求头执行 zod schema 校验非法请求会被拦截不会进入业务处理函数schema 类型直接流向handle(...)zod 的z.infer类型会沿调用链传递因此handle的参数input自带类型信息可以直接写出input.params.id无需手写一遍 TS 接口前后端契约单一来源single source of truth。仓库示例 user.api.ts 还展示了带meta的写法通过.meta({ routerName: getUser })给路由一个稳定的操作名该名称会作为operationId的一部分被 client 使用。4. 创建前端 client把服务端 API 定义变成可调用的客户端对象前端只需要从midwayjs/react或midwayjs/vue导入createClient把服务端 API 定义按命名空间传入即可得到类型安全的调用对象。React// src/web/api/client.ts import { createClient } from midwayjs/react; import { userApi } from ../../server/api/user.api; export const api createClient( { user: userApi }, { basePath: /api } );Vue// src/web/api/client.ts import { createClient } from midwayjs/vue; import { userApi } from ../../server/api/user.api; export const api createClient( { user: userApi }, { basePath: /api } );从源码看这两个包的createClient都是对 midwayjs/web-bridge 的 createClient 的再导出React 侧见 bridge.tsVue 侧见 index.ts。底层createClient会遍历每个模块的路由拼出operationId形如user.getUser、method与fullPath最终生成形如api.user.getUser(input)的调用函数并附带call(operationId, input)、has(operationId)、operationIds()三个通用方法。关于basePath的进阶用法basePath除了字符串还支持对象或函数见 CreateClientOptions。在 SSR / 同构场景下浏览器与 Node 端需要不同的基地址——浏览器访问/api同源相对路径服务端渲染时访问http://127.0.0.1:7001/api绝对地址。示例项目 client.ts 正是这样配置的export const api createClient( { user: userApi }, { basePath: { browser: /api, server: http://127.0.0.1:7001/api, }, } );resolveRuntimeBasePath见 api-bridge 源码会依据运行环境是否检测到window.document自动选择browser/server分支。默认的 HTTP transport 使用全局fetch作为底层 adapter路径参数通过encodeURIComponent安全替换、query 用URLSearchParams序列化如果项目已接入 axios也可以使用createAxiosAdapter(axiosInstance)替换默认 fetch 实现createAxiosAdapter。5. 在页面里调用像调用本地函数一样调用远端 APIReact 页面组件import { useEffect, useState } from react; import { api } from ./api/client; export function UserPage() { const [name, setName] useState(); useEffect(() { api.user.getUser({ params: { id: u-1 } }).then(user { setName(user.name); }); }, []); return div{name}/div; }Vue 的setup()// setup() const user await api.user.getUser({ params: { id: u-1 }, });调用约定非常直观输入对象固定为{ params, query, body, headers }四个可选字段分别对应路径参数、查询串、请求体与请求头HttpClientInputShape与第 3 节input(...)声明的校验维度一一对应。api.user.getUser的返回值类型由服务端.output(z.object({...}))推导而来因此user.name无需任何手动类型标注。Vue 生态还额外提供了依赖注入式的用法MidwayApiProvider组件或createMidwayApiPlugin(client)插件向应用注入 client组件内通过useMidwayApiClient()/useMidwayApiOperation(operationId)取用详见 Vue 封装源码适合需要把 client 与组件解耦的场景。6. 配置 Vite 桥接devPlugin apiPlugin 双插件这是前后端接起来的关键一步。在vite.config.ts中同时启用两个插件import { defineConfig } from vite; import { devPlugin } from midwayjs/mock/vite; import { apiPlugin } from midwayjs/web-bridge/vite; export default defineConfig({ plugins: [ devPlugin({ appDir: process.cwd(), baseDir: src/server, basePath: /api, }), apiPlugin({ root: process.cwd(), apiDir: src/server/api, target: both, }), ], });两个插件职责分明devPlugin来自 midwayjs/mock 的 vite 插件把 Midway 函数式应用作为请求处理器挂到 Vite 开发服务器上。appDir指向项目根目录baseDir指向服务端代码目录src/serverbasePath指定接口前缀/api浏览器发往/api/*的请求由此进入 Midway 处理apiPlugin来自 midwayjs/web-bridge 的 vite 插件apiDir指向服务端 API 定义目录target决定转换作用于哪个构建目标client纯浏览器构建、ssr仅服务端渲染构建或both两者都生效。apiPlugin的底层原理值得了解它以\0midway-api:前缀创建虚拟模块在resolveId阶段拦截对apiDir内、且包含defineApi的文件的导入用 transformDefineApiSource 做一次轻量源码扫描——只提取defineApi的prefix、各路由的method/path与meta信息生成纯浏览器安全的路由契约代码toCode服务端的handle业务逻辑与 zod 校验器不会被打进前端包。插件还会通过addWatchFile与handleHotUpdate支持 API 定义文件的热更新。React 项目记得再加vitejs/plugin-reactVue 项目再加vitejs/plugin-vue。完整的真实配置可对照示例项目 vite.config.ts——其中basePath直接复用了 client 里声明的apiBridgeConfig.browserBasePath避免两处硬编码不一致。7. 函数式中间件路由级与模块级两种挂载方式函数式 API 的中间件支持两种作用域路由级——只对单个路由生效通过.meta({ middleware: [...] })挂载api.get(/:id).meta({ middleware: [authMw] }).handle(async () ({}));模块级——对整个 API 模块下的所有路由生效通过defineApi的第三个参数挂载defineApi(/users, api ({ getUser: api.get(/:id).handle(async () ({})), }), { middleware: [authMw], });两种方式都可叠加多个中间件典型的场景如鉴权authMw、日志、限流等横切逻辑写在函数式 API 层可以复用到所有前端调用方。8. 启动与验证运行$ npm run dev启动开发服务器打开页面触发一次 API 调用例如进入UserPage在浏览器开发者工具的网络面板中确认请求命中/api/*如GET /api/users/u-1。验证通过的标准请求确实进入了 Midway 函数式 API 处理、响应结构与output(...)声明的 schema 一致、前端user.name渲染出服务端返回的harry。9. Rspack 场景可选如果构建工具不是 Vite 而是 Rspackmidwayjs/web-bridge提供对应的 loader 与 rule 工厂。在 Rspack 配置中直接使用createApiRspackRule({ root: process.cwd(), apiDir: src/server/api, });该工厂返回一条enforce: pre的 rulecreateApiRspackRuletest匹配\.[cm]?[jt]sx?$文件include限定在apiDir内use指向midwayjs/web-bridge/rspackloader。loader 内部apiRspackLoader复用与 Vite 插件同一套toWebSafeApiContractCode转换逻辑将defineApi源码改写为浏览器安全的路由契约代码——因此 Vite 与 Rspack 两套链路得到的契约语义完全一致。10. 自定义目录说明src/web/api与src/server/api只是推荐目录不是强制约定。你可以改成src/client/api、src/apis等其他任意位置只要保证以下两处同步即可前端client.ts的真实路径与导入路径client.ts中import { userApi } from ../../server/api/user.api的相对路径必须与实际存放服务端 API 定义的位置一致构建插件apiDir指向正确的服务端 API 定义目录vite.config.ts/ Rspack 配置里的apiDir必须指向同一个目录否则apiPlugin/createApiRspackRule无法扫描到defineApi前端也就拿不到对应的路由契约。小结一条可复制的全栈落地链路回顾整条链路defineApi用 zod 声明输入输出服务端契约唯一来源→midwayjs/react|vue的createClient把契约变成类型安全的调用对象 →devPlugin让 Vite 直接处理/api/*请求 →apiPlugin/createApiRspackRule把服务端 API 定义转换为浏览器安全的路由契约并随文件热更新。整条链路的核心实现分别位于 api-bridge 客户端内核、web-bridge 构建插件 与 Rspack loader配合 react-functional-api 完整示例 可直接对照落地。赞分享后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载相关推荐Midway 函数式 API 与 Vue 前端集成指南从 defineApi 到 createClient 的端到端打通Midway 函数式 API 与 Vue 前端集成指南从 defineApi 到 createClient 的端到端打通 本篇技术指南以 site/docs/后端微服务云原生Midway Functional Web Routing API 设计指南defineApi 链式 DSL、纯函数式服务与 React/Vue 前后端一体化开发Midway Functional Web Routing API 设计指南defineApi 链式 DSL、纯函数式服务与 React/Vue 前后端一体化后端微服务云原生在 Vue 3 中调用 Midway 函数式 APImidwayjs/vue 桥接插件与组合式 API 实践指南在 Vue 3 中调用 Midway 函数式 APImidwayjs/vue 桥接插件与组合式 API 实践指南 导读 midwayjs/vue 是 Mi后端微服务云原生上一篇终极指南如何快速掌握ModSecurity v3 Web应用防火墙下一篇【亲测免费】 Stable Diffusion 开源项目教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考