多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Relay 中的 UploadableMap:文件上传类型与数据流深度解析

Relay 中的 UploadableMap:文件上传类型与数据流深度解析 前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载UploadableMap 是 Relay Runtime 中定义文件上传能力的基础类型它以文件名/字段名 → File 或 Blob的键值对形式为 GraphQL mutation 上传文件提供标准化的输入结构。本文将基于当前仓库 v18 版本文档与源码讲解该类型的准确定义、在 mutation 提交链路中的传递路径、网络层接收与处理的约定以及使用中的限制与最佳实践帮助你写出可实际运行的文件上传 mutation 代码。类型定义一段被引用的核心约定UploadableMap在官方 API 参考文档中仅有简洁的一条定义一个对象其值类型为File或Blob。虽然文档极简但它在 Relay 运行时relay-runtime中是一个贯穿用户 API → 环境执行 → 网络层的全局类型。其真实源码定义位于 RelayNetworkTypes.jsFlow 版本与 RelayNetworkTypes.d.tsTypeScript 版本// Flow 版本 export type Uploadable File | Blob; export type UploadableMap {readonly [key: string]: Uploadable};// TypeScript 版本 export type Uploadable File | Blob; export interface UploadableMap { [key: string]: Uploadable; }从定义可以看出三个关键约定键key上传项的标识通常对应服务端解析时使用的字段名或文件名一个键代表一个上传项值value必须是浏览器环境中的File或Blob对象二者都是二进制数据的包装File是带文件名和 MIME 类型的特殊Blob只读语义Flow 版本使用readonly修饰整个对象表示该映射在传入后不应被修改。在运行时中的传递路径从 commitMutation 到网络层UploadableMap不是孤立存在的类型它随 mutation 提交请求一起流动。完整链路为commitMutation / useMutation → environment.executeMutation() → network.execute() → 用户自定义 fetch 函数入口一commitMutation 配置项命令式 APIcommitMutation在 commitMutation.js 中定义MutationConfig与CommitMutationConfig两者都包含可选的uploadables?: UploadableMap字段。函数内部将其解构后随请求一起执行const {configs, cacheConfig, onError, onUnsubscribe, variables, uploadables} config; // ... environment .executeMutation({ operation, optimisticResponse, optimisticUpdater, updater, uploadables, // 透传给 environment }) .subscribe({...});对应 TypeScript 声明位于 commitMutation.d.tsuploadables?: UploadableMap | null | undefined。入口二useMutation Hook在 React Hooks 场景下useMutation返回的提交函数同样接受uploadables配置见 useMutation.js 中的UseMutationConfig。官方 useMutation API 参考 对此给出了直接解释uploadables可选的上传映射一个对象表示任意数量的可上传项每个项一个键每个值必须是File或Blob类型。中间层environment.executeMutationRelayModernEnvironment的 executeMutation 接收uploadables后构造网络请求的 sourceexecuteMutation({operation, optimisticResponse, optimisticUpdater, updater, uploadables}) { // ... return this._execute({ createSource: () this.getNetwork().execute( operation.request.node.params, operation.request.variables, {...operation.request.cacheConfig, force: true}, uploadables, // 最终传入网络层 ), // ... }); }多 actor 环境multi-actor environment中的 executeMutation 也采用完全相同的透传方式说明该类型在所有环境实现中语义一致。终点网络层 execute 与 fetch 函数网络层通过Network.create(fetchFn)创建RelayNetwork.js 的execute签名中即包含uploadables?: ?UploadableMap并将它连同请求参数、变量、cacheConfig 一起传给用户实现的 fetch 函数。在自定义网络层中fetch函数签名FetchFunction的第五个位置参数即为uploadables定义见 RelayNetworkTypes.js。wrapNetworkWithLogObserver等包装层也原样传递该参数见 wrapNetworkWithLogObserver.js。实战用 UploadableMap 上传文件1. 编写 mutation服务端需要定义一个接收二进制上传的 GraphQL mutation例如mutation UploadFileMutation($input: UploadFileInput!) { uploadFile(input: $input) { id url } }2. 构造 UploadableMap 并提交文件上传发生在浏览器环境用户通常从input typefile或拖拽事件中取得File对象。以useMutation为例import {useMutation, graphql} from react-relay; function FileUploader() { const [commit, isInFlight] useMutation(graphql mutation UploadFileMutation($input: UploadFileInput!) { uploadFile(input: $input) { id url } } ); function handleFile(e) { const file e.target.files[0]; commit({ variables: {input: {id: avatar, filename: file.name}}, uploadables: { // 键名对应服务端解析约定值为 File 或 Blob file, }, onCompleted(data) { console.log(上传成功, data); }, onError(error) { console.error(上传失败, error); }, }); } return ( div input typefile onChange{handleFile} / button disabled{isInFlight}上传中…/button /div ); }使用命令式commitMutation时写法等价uploadables同样是配置对象的一员import {commitMutation} from relay-runtime; commitMutation(environment, { mutation, variables: {input: {...}}, uploadables: {file: blobOrFile}, onCompleted, onError, });3. 在自定义网络层中处理二进制数据默认网络层示例见 network-layer.md只发送 JSON。若要支持文件上传fetch 函数需检测uploadables是否存在并切换为multipart/form-data编码import {Network, Environment, Store, RecordSource} from relay-runtime; function fetchQuery(operation, variables, cacheConfig, uploadables) { if (uploadables) { // 存在文件时使用 FormData 以 multipart/form-data 上传 const formData new FormData(); formData.append(query, operation.text); formData.append(variables, JSON.stringify(variables)); Object.keys(uploadables).forEach(key { formData.append(key, uploadables[key]); }); return fetch(/graphql, {method: POST, body: formData}).then(res res.json(), ); } // 无文件时仍走普通 JSON 请求 return fetch(/graphql, { method: POST, headers: {content-type: application/json}, body: JSON.stringify({query: operation.text, variables}), }).then(res res.json()); } const network Network.create(fetchQuery); const environment new Environment({network, store: new Store(new RecordSource())});官方网络层文档也明确指出该扩展点可扩展添加……针对 mutation 上传表单数据的功能uploadables参数见 network-layer.md。使用限制与注意事项UploadableMap并非适用于所有操作类型。在 RelayNetwork.js 的execute中存在两条硬性约束if (request.operationKind subscription) { invariant( !uploadables, RelayNetwork: Cannot provide uploadables while subscribing., ); // ... } if (pollInterval ! null) { invariant( !uploadables, RelayNetwork: Cannot provide uploadables while polling., ); // ... }即subscription订阅不允许携带uploadables否则抛出RelayNetwork: Cannot provide uploadables while subscribing.轮询polling当cacheConfig.poll被设置时同样禁止携带uploadables。因此UploadableMap实际只服务于 mutation 场景这与其在MutationConfig、UseMutationConfig中出现、而在查询相关配置中缺席的事实一致。类型与导出UploadableMap与Uploadable由 relay-runtime 统一导出TypeScript 类型声明位于 index.d.tsFlow 版本位于 index.js供useMutation、commitMutation、RelayModernEnvironment、RelayNetworkTypes等模块共同引用。仓库测试如 RelayNetwork-test.js中也将_uploadables: ?UploadableMap作为 fetch mock 的签名参数验证传递行为可作进一步参考。小结UploadableMap定义虽短却是 Relay 文件上传能力的契约中心它以{[key: string]: File | Blob}的结构承载上传项从commitMutation/useMutation进入经executeMutation透传至网络层最终由自定义 fetch 函数以multipart/form-data发送。记住两条使用边界——仅用于 mutation、不可用于订阅与轮询——即可稳定落地文件上传功能。赞分享前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载相关推荐Relay 19 文件上传指南深入解析 UploadableMap 类型与 uploadables 的完整数据流Relay 19 文件上传指南深入解析 UploadableMap 类型与 uploadables 的完整数据流 UploadableMap 是 Relay前端开发工具Relay 文件上传类型 UploadableMap 深入解析Mutation 中 File/Blob 的传递机制与实战Relay 文件上传类型 UploadableMap 深入解析Mutation 中 File/Blob 的传递机制与实战 导读 UploadableMap 是前端开发工具Relay UploadableMap 类型全解析从类型定义到文件上传实战Relay UploadableMap 类型全解析从类型定义到文件上传实战 导读 UploadableMap 是 Relay 运行时中用于携带文件上传数据的核前端开发工具上一篇Conferences.digitalMac上最佳开发者会议视频观看工具完全指南下一篇Project Guidelines创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表