ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

NocoBase RunJS APIResource:基于 URL 发起 HTTP 请求的通用资源深度解析

NocoBase RunJS APIResource:基于 URL 发起 HTTP 请求的通用资源深度解析 NocoBase RunJS APIResource基于 URL 发起 HTTP 请求的通用资源深度解析【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase在 NocoBase 的 RunJS 运行时中APIResource 是一个面向任意 HTTP 接口的通用请求资源。本文以 RunJS 文档为骨架结合 flow-engine 包中的真实源码 与单元测试完整讲清 APIResource 的适用场景、请求配置方法、URL 格式、refresh()数据拉取流程与错误处理机制。读完本文你能够熟练使用ctx.makeResource(APIResource)对接自定义接口与第三方 API并理解其响应式数据、事件与错误状态在底层是如何实现的。什么是 APIResourceAPIResource 是一个基于 URL 发起请求的通用 API 资源适用于任意 HTTP 接口。它继承自 FlowResource 基类并扩展了请求配置与refresh()方法。与同目录下的 MultiRecordResource、SingleRecordResource 不同APIResource不依赖资源名直接按 URL 请求因此特别适合自定义接口、第三方 API 等场景。创建方式ctx.makeResource(APIResource)或ctx.initResource(APIResource)。使用前需设置setURL()RunJS 上下文中会自动注入ctx.apiAPIClient无需手动setAPIClient。从源码结构看资源实例的创建入口在 FlowContextflowContext.ts 中makeResource/initResource的签名明确将APIResource | SingleRecordResource | MultiRecordResource | SQLResource列为支持的资源类名其中initResource会把资源绑定到ctx.resource若上下文中已有 resource 则直接跳过makeResource则新建实例不绑定。所有可用资源类在 FlowEngine 构造函数 中通过registerResources统一注册APIResource 即其中之一。适用场景场景说明自定义接口调用非标准资源 API如/api/custom/stats、/api/reports/summary第三方 API通过完整 URL 请求外部服务需目标支持 CORS一次性查询临时拉取数据用完即弃无需绑定到ctx.resource与 ctx.request 的取舍需要响应式数据、事件、错误状态时用 APIResource简单一次性请求可用ctx.request()这个取舍在源码中能得到印证APIResource 内部将_data、_meta、_error三个状态全部用 formily 的observable.ref包裹见 flowResource.ts因此数据变化可以驱动 UI 响应式更新而ctx.request()只是一次普通请求没有任何状态容器。基类能力FlowResource所有 Resource 均具备 FlowResource 提供的通用能力方法说明getData()获取当前数据setData(value)设置数据仅本地hasData()是否有数据getMeta(key?)/setMeta(meta)读写元数据getError()/setError(err)/clearError()错误状态on(event, callback)/once/off/emit事件订阅与触发几个源码层面的细节值得注意响应式存储_data、_meta、_error均为observable.ref对数据、元数据、错误状态的读写都可被响应式系统追踪错误模型基类定义了 ResourceError它会从原始异常的response.data中解析出可读错误信息error、errors、messages字段并暴露code缺省为UNKNOWN_ERROR与message两个 getter供 RunJS 脚本统一取用事件机制on/once/off/emit是轻量的自实现事件总线once通过包装回调并在触发后off实现自动移除refresh成功事件即由emit(refresh)触发。请求配置APIResource 在 apiResource.ts 中维护一个内部request配置对象初始结构为{ headers: {}, params: {}, method: get, data: null }并围绕它提供完整的配置方法方法说明setAPIClient(api)设置 APIClient 实例RunJS 中通常由上下文自动注入getURL()/setURL(url)请求 URLloading读写加载状态get/setclearRequestParameters()清空请求参数setRequestParameters(params)合并设置请求参数setRequestMethod(method)设置请求方法如get、post默认getaddRequestHeader(key, value)/removeRequestHeader(key)请求头addRequestParameter(key, value)/getRequestParameter(key)/removeRequestParameter(key)单参数增删查setRequestBody(data)请求体POST/PUT/PATCH 时使用setRequestOptions(key, value)/getRequestOptions()通用请求选项链式调用上述配置方法几乎全部返回this因此可以像 单元测试 中那样连写r.setURL(/api/x) .setRequestMethod(post) .addRequestHeader(X-Token, abc) .setRequestParameters({ a: 1 }) .setRequestBody({ k: v }) .setRequestOptions(timeout, 1000);两个关键行为均有测试用例验证参数是合并而非覆盖setRequestParameters的实现为this.request.params { ...this.request.params, ...params }连续调用{ a: 1, b: 2 }后{ b: 3, c: 4 }最终得到{ a: 1, b: 3, c: 4 }见 测试第 56-61 行。需要彻底重置时应调用clearRequestParameters()。getRequestOptions()返回内部对象的引用测试 第 171-200 行 特意验证了对外部返回对象的原生修改会同步反映到资源内部状态。也就是说getRequestOptions()返回的是“活”的配置setRequestOptions(timeout, 1000)这类通用选项最终也会随请求一起发出。setAPIClient并非简单赋值源码中它调用getDirtyAwareApiClient(api, this.context)对传入的 APIClient 做了包装见 apiResource.ts 第 36-39 行因此即便手动注入 client也能感知上下文脏状态。RunJS 场景下构造函数会直接从context.api取用第 29-34 行一般无需手动设置。另外loading是一个 getter/setter 对底层读取/写入 meta 中的loading键默认false测试 第 86-100 行 确认了r.loading true与r.getMeta(loading)的联动。URL 格式资源风格支持 NocoBase 资源简写如users:list、posts:get会与 baseURL 拼接相对路径如/api/custom/endpoint与应用的 baseURL 拼接完整 URL跨域时使用完整地址目标需配置 CORS资源风格的 URL 意味着你可以用 APIResource 以“通用方式”调用 NocoBase 标准资源接口资源名:动作同时保留 URL 级别的参数、请求头定制能力——这是对 MultiRecordResource 等面向模型的资源的一种补充视角。数据拉取refresh() 的完整流程refresh()是 APIResource 的核心方法按当前 URL、method、params、headers、data 发起请求将响应data写入setData(data)并触发refresh事件失败时设置setError(err)并抛出ResourceError不触发refresh事件。调用前必须已设置api与 URL。对照 refresh() 源码其执行流程为前置检查this.api未设置时直接抛出Error(API client not set)测试用例 验证清空旧错误调用clearError()保证每次请求从干净的错误状态开始发起请求this.api.request({ url: this.getURL(), ...this.getRefreshRequestOptions() })其中getRefreshRequestOptions()返回整个内部request配置的展开副本即 url、method、headers、params、data 及自定义选项一次性传给 APIClient成功路径setData(data)后emit(refresh)——注意写入的是响应体中的data字段而非整个响应失败路径将原始异常包装为ResourceErrorsetError(error)后重新throw且不触发refresh事件。单元测试 对这三条路径都有覆盖成功时断言getData()更新、getError()为null、onRefresh恰好触发一次、api.request收到合并后的配置失败时断言预置的 data保持不变、refresh 事件未触发、抛出的是ResourceError实例。示例基础 GET 请求const res ctx.makeResource(APIResource); res.setURL(/api/custom/endpoint); res.setRequestParameters({ page: 1, pageSize: 10 }); await res.refresh(); const data res.getData();资源风格 URLconst res ctx.makeResource(APIResource); res.setURL(users:list); res.setRequestParameters({ pageSize: 20, sort: [-createdAt] }); await res.refresh(); const rows res.getData()?.data ?? [];这里users:list对应 NocoBase 标准的资源风格接口返回结构为{ data: [...] }故取getData()?.data。POST 请求带请求体const res ctx.makeResource(APIResource); res.setURL(/api/custom/submit); res.setRequestMethod(post); res.setRequestBody({ name: 测试, type: report }); await res.refresh(); const result res.getData();监听 refresh 事件const res ctx.makeResource(APIResource); res.setURL(/api/stats); res.on(refresh, () { const data res.getData(); ctx.render(div统计: {JSON.stringify(data)}/div); }); await res.refresh();由于_data是响应式的refresh事件适合与ctx.render组合每次数据刷新后驱动 UI 更新。错误处理const res ctx.makeResource(APIResource); res.setURL(/api/may-fail); try { await res.refresh(); const data res.getData(); } catch (e) { const err res.getError(); ctx.message.error(err?.message ?? 请求失败); }失败时getData()保持原值源码中 catch 分支不会调用setData测试亦验证了这一点错误信息应通过getError()获取ResourceError自带解析好的message与code可直接用于提示。自定义请求头const res ctx.makeResource(APIResource); res.setURL(https://api.example.com/data); res.addRequestHeader(X-Custom-Header, value); res.addRequestParameter(key, xxx); await res.refresh();完整 URL 用于跨域请求外部服务目标端需配置 CORS。注意事项ctx.api 依赖RunJS 中ctx.api由运行环境注入通常无需手动setAPIClient若在无上下文的场景使用如直接new FlowEngine().createResource(APIResource)需自行设置否则refresh()会抛出API client not set。refresh 即请求refresh()会按当前配置发起一次请求method、params、data 等需在调用前配置好配置是“快照式”的——refresh内部对内部request对象做展开拷贝传入 APIClient因此请求发出前对配置的修改才会生效。错误不更新 data请求失败时getData()保持原值可通过getError()获取错误信息且refresh事件不会触发。与 ctx.request 的取舍简单一次性请求可用ctx.request()需要响应式数据、事件、错误状态管理时用 APIResource。相关资源ctx.resource — 当前上下文中的 resource 实例ctx.initResource() — 初始化并绑定到 ctx.resourcectx.makeResource() — 新建 resource 实例不绑定ctx.request() — 通用 HTTP 请求适合简单一次性调用MultiRecordResource — 面向数据表/列表支持 CRUD、分页SingleRecordResource — 面向单条记录关键源码与测试路径内容路径APIResource 实现packages/core/flow-engine/src/resources/apiResource.tsFlowResource 基类与 ResourceErrorpackages/core/flow-engine/src/resources/flowResource.ts资源注册packages/core/flow-engine/src/flowEngine.ts单元测试packages/core/flow-engine/src/resources/tests/apiResource.test.ts【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表