@ cratestack/ refine (英语)
A 类 精炼.dev DataProvider 超过 CrateStack 生成的 TypeScript 客户端 ——
资源 (单位:千美元)createCratestackDataProvider)或(或) 难民保护委员会 (单位:千美元)createCratestackRpcDataProvider,用于
transport rpc 计划。 电线精炼器修好了 getList编号 :getOne编号 :getMany编号 :create编号 :update编号 :
deleteOne 表面到生成的模型类( e)client.widgets, (中文(简体) ), client.ledgers),绘图
精炼的滤波操作器、相接键、主键和 @version 乐观冲突
输入服务器的真实合同——同一合同 板条板球
故意绕道. cratestack-studio 会谈 [target.db] 直接跳过 @@allow页:1
精炼基于此软件包的应用通过生成的API并继承政策,验证,
@version 货币和审计。 这就是这个软件包存在的原因(cratestack#571):精炼
是安全的终端用户管理员 工作室是系统管理员.
两家运输公司都分享同样的README,除非有一节另有说明
getList编号 :getOne编号 :getMany编号 :create编号 :update编号 :deleteOne编号 :createMany编号 :updateMany编号 :deleteMany编号 :
custom 行为、过滤操作器表、发光语义、主键处理和 @version
乐观锁定的保证是相同的;只有下面的电线调用不同。 见
RPC 运输 说明RPC的具体内容,以及 范围 为了什么
供养者有.
带有生成运单的运行时包
A 类 DataProvider 每个资源需要四个东西——生成的 API 对象本身,模型的
主键字段名称, 是否声明 @@paged,以及是否/其中声明 @version。 。 。 .
没有人有 运行时间 发现路径: 生成的客户端没有 $meta 对象和否
透视结束点, 仅限其类型脚本 类型 在编译时已编码
(确认为真实生成) client.ts编号 :models.ts 这个软件包自己的测试驱动器——见
测试/) (中文(简体) ). 因此,提供者本身必须是手写运行时函数
它的逻辑中没有任何图谋可以产生.
这个 显示 这是另一个问题, 板条板#571 解决它的另一方式:
事实都存在 .cstack 计划,所以发电机释放出来。 过 --refine 改为
cratestack generate-typescript 它会写一个额外的 src/refine.ts 在客户端旁边:
cratestack generate-typescript \
--schema schema.cstack \
--out ./generated \
--refine
// generated/src/refine.ts — generated, do not edit
export function cratestackRefineResources(client: ExampleApiClientClient): ResourceMap { … }
手写显示的仍然被完全支持(它是一个普通的物体字面,每个
下面的例子显示一个),但生成的模型不能漂移:一个获得收益的模型 @version,或一个
谁 @id 未调用 id时,更新其下个 generate-typescript 运行代替
在运行时悄悄失败.
--refine 工作为 两者 REST和RPC计划。 释放的函数也是一样的形状
办法.. cratestackRefineResources(client) — 已输入 ResourceMap 技术开发和转让 RpcResourceMap 页:1
RPC,因此整个运输过程中的消费代码是相同的. 也可以自由编曲
--swr (文件/模型+钩子布局, <package-name>/swr曰:表相会相会
总是允许默认布局的客户类 不论那面旗帜。 见 范围。 。 。 .
用法(REST)
与所生成的表:
import { createCratestackDataProvider } from "@cratestack/refine";
import { ExampleApiClientClient } from "./generated/src/client.js";
import { cratestackRefineResources } from "./generated/src/refine.js";
const client = new ExampleApiClientClient("https://api.example.com", { basePath: "/api" });
const dataProvider = createCratestackDataProvider(cratestackRefineResources(client));
或写出显示自己——相同的形状,以及生成的文件包含的内容:
const dataProvider = createCratestackDataProvider({
widgets: { api: client.widgets, primaryKey: "id", paged: false },
ledgers: { api: client.ledgers, primaryKey: "id", paged: true, versionField: "version" },
products: { api: client.products, primaryKey: "sku", paged: false },
});
把这个直接递给精炼师 <Refine dataProvider={dataProvider} .../>。 。 。 .
RPC 运输
对a transport rpc 计划, 使用 createCratestackRpcDataProvider 还有一个 RpcResourceMap 换成
- 每项资源有相同的四个事实(api, (中文(简体) ), primaryKey, (中文(简体) ), paged选项 versionField),同样
getList编号 :getOne/... / 说custom 行为,相同的过滤操作表和 @version 保证为
师曰. --refine 生成 RPC 方案表, 键入 RpcResourceMap (见上文);
手写的,看起来是这样的:
import { createCratestackRpcDataProvider } from "@cratestack/refine";
import { ExampleApiClientClient } from "./generated/src/client.js";
const client = new ExampleApiClientClient("https://api.example.com", { basePath: "/api" });
const dataProvider = createCratestackRpcDataProvider({
widgets: { api: client.widgets, primaryKey: "id", paged: false },
ledgers: { api: client.ledgers, primaryKey: "id", paged: true, versionField: "version" },
products: { api: client.products, primaryKey: "sku", paged: false },
});
和REST有什么不同,机械上:
- 生成的 RPC 模型类
list以查询定位 (单位:千美元)list(query, options))而不是在选项中嵌入,对象为REST的方式list({ query, headers, signal })是否为 --createCratestackRpcDataProvider构建一个RpcListQuery(RPC键入) 列表输入形状)而不是 REST 的CratestackFetchQuery。 。 。 .get编号 :create编号 :update编号 :delete为: 两种运输方式的位置相同;只有它们的选项类型不同 (单位:千美元)CratestackRpcCallOptions对CratestackRequestConfig) (中文(简体) ). - 过滤器编译到
RpcListPredicate[](单位:千美元){ key, value }(对)而不是REST的Record<string,string>- 一样field[__operator]关键公约(见 过滤器 下方,钢丝上有一个不同的容器形状. - 将编译到单个逗号连接字符串( S)
"-createdAt,id") 而不是REST的(英语:string[]运行时间加入客户端- 相同field编号 :-fieldDSL. (英语). - 每一个空闲的电话都带着
If-Match和REST一样. 皇家警察派来武器 (单位:千美元)crates/cratestack-macros/src/transport/rpc.rs通过真正的HTTPHeaderMap直接穿过 改为:handle_update_*_dispatch编号 :handle_delete_*_dispatchfns REST 用途 (单位:千美元)crates/cratestack-macros/src/axum/model/handlers_update.rs)改为:If-Match通过parse_if_match_version所以,一个 stale 或缺少If-Match反对:@version模式返回 不变412 Precondition Failed根据实际生成的 RPC 客户端在 此软件包自己的测试套件( name of translators)tests/rpc-optimistic-locking.test.ts) (中文(简体) ). createCratestackRpcDataProvider从不打电话POST /rpc/batch。 。 。 . 批量请求是 HTTP 请求中包含 N 帧,所以每个帧If-Match信头是无法表达的..createMany编号 :updateMany编号 :deleteManyn 是真实的无线往返, 而非原子 可再生能源技术战略用途(见 创建 Many / 更新 Many / 删除 Many 页:1 一个分批的RPC数据提供者原则上是可能的,但在此范围之外——见 范围。 。 。 .
过滤器
适用于两个供应商。 精细 CrudFilters (单位:千美元){ field, operator, value }) 映射到同一地点
field[__operator] 关于这两种运输的关键公约——REST公约 field__operator=value 查询段落
(单位:千美元)toQueryFilters) 和RPC(RPC)的 RpcListPredicate[] (单位:千美元)toRpcQueryFilters载有相同的 key, (中文(简体) ),
铁丝网上不同的容器形状 相同的运算符设置生成的客户端共享
过滤器类型( e)EqualityFilter编号 :ComparableFilter编号 :StringFilter揭露:
| 精细操作器 | 板条链查询密钥 |
|---|---|
eq | field (无后缀) |
ne | field__ne |
in | field__in (合并分离) |
lt 编号 : lte 编号 : gt 编号 : gte | field__lt 编号 : __lte 编号 : __gt 编号 : __gte |
contains | field__contains |
startswith | field__startsWith |
null | field__isNull=true |
nnull | field__isNull=false |
其它精细操作员扔出 —— 说 endswith, (中文(简体) ), between, (中文(简体) ), nin, (中文(简体) ), containss精细
or编号 :and 过滤组, 以及上表中没有的任何东西 。 丢弃不支持的过滤器
默默地显示错误的数据,好像它已被过滤过一样;一个错误绝对更好. 说明
并且 eq编号 :ne编号 :in/ 比较运算符只针对 所需经费 (不可撤销)字段
那是服务器侧的密码门
(单位:千美元)crates/cratestack-macros/src/axum/filter_arms.rs::generate_query_filter_arm不是这个
软件包可以左右工作.
倾斜
适用于两个供应商。 精细 { current, pageSize } 地图到 limit编号 :offset 直接说.
totalCount 只有永远
为a 排放 @@paged 模型列表路线. 设定 paged: false 在资源配置 诚实地 -
a 不包括:@@paged 资源 getList 仍然返回真实数据,但 total 降解为
"多少行此一回回回",而不是真实的计数. 增加一个 @@paged 页:1
模型,或配置精细 pagination: { mode: "off" } 资源,并将结果作为
1 (封面)页.
主密钥
适用于两个供应商。 精细的假设每个记录 id: BaseKey. . . . . . . @id 可以在任意领域
(单位:千美元)primaryKey ,在上方的资源配置中)。 每一个回回的唱片都得到合成 id 字段
加上它真正的主键 所以精炼的行选机械 有一些关键;
写( a)get编号 :update编号 :deleteOne) 得到同样的值返回并直接传递至
真正的主要关键——不需要翻译,因为 值空间 完全一样。 一个地方
这个咬: a <Create> 窗体的字段必须使用 schema 真正的主键字段名(例如).
sku(没有) id ——创出的有效载荷尚未有合成记录 id 从.
优化锁定( O)@version 编号 : If-Match(中文(简体) )
这个包件中唯一最重要的正确性点,它坚持两种运输.
A 类 @version 模式要求 If-Match 两次更新 财务报告和审定财务报表 删除(cratestack#493/#519#538)-
缺少或陈旧 If-Match 返回时 412 Precondition Failed 使行无碍
请求作为RPC的无名电话或REST发出 PATCH编号 :DELETE (见
RPC 运输 为什么RPC的发送路径执行这个和REST相同).
精细 update编号 :deleteOne 钩子在编辑前获取记录,所以该版本由
;每个提供者记得它(按 createCratestackDataProvider编号 :
createCratestackRpcDataProvider 调用,而不是模块-全局),来自每个返回 a 的读取/写入
新的记录,并自动发送。 A 类 412 表面为
可区分的冲突(statusCode: 412而不是普通的
失败——检查 error.statusCode === 412 在一个 onError 处理器显示“其他人改变了”
而不是一般的.
过 meta: { ifMatch: <version> } 改为 update编号 :deleteOne 以明确覆盖缓存(例如).
(原始内容存档于2017-10-21) (中文(中国大陆) ). Orious-lock-aware problem works. 通话 update编号 :deleteOne 编号 @version 资源无
已知的版本, 没有覆盖 扔出而不是默默省略 If-Match - 省略它不会
在电线上失败了 暂停 值确实如此,所以这个软件包拒绝为您犯错误.
错误
每一种方法都以同样的方式转换,而转换永远不会破坏被抛出的东西. 全体人员
getList, (中文(简体) ), getMany, (中文(简体) ), getOne, (中文(简体) ), create, (中文(简体) ), update, (中文(简体) ), deleteOne 财务报告和审定财务报表 custom 路由一个抛出值
结束 toRefineError (出口,所以你可以再利用)——没有任何方法可以将生和
没有方法,其误差可以改进 statusCode (cratestack #786; 在此之前修复两者)
列表方法与四种单一记录方法不一致,您击出哪种方法取决于
屏幕上显示用户。).
改划 注释已丢入的值 而不是替换它。 如果你的运输
扔出已打出的错误, 值为 onError 处理器接收 实值 该错误 :
class DeviceNotEnrolledError extends Error {}
// works identically on list screens and on detail/create/edit screens
if (error instanceof DeviceNotEnrolledError) { … }
message 财务报告和审定财务报表 statusCode 这才是精炼的 CratestackHttpError
拿信封来 payload.message 晋升,a 412 得到乐观锁定的消息
上,同时 status编号 :payload编号 :response 在同一对象上保留可读性。 当抛出值
无法附加注释(抛出原始对象、被冻结的对象),您得到 { message, statusCode, cause }
原文列在下 cause。 。 。 .
不通过字符串匹配来分类错误 message ——这是允许进行的一个字段转换
重写.
createMany 编号 : updateMany 编号 : deleteMany
已在两个供应商中执行,没有减少,但因N次连续单次记录往返旅行
(单位:千美元)Promise.all 结束 create编号 :update编号 :deleteOne),不是真正的批发. 生成的 REST 客户端
显示没有 updateMany编号 :deleteMany 围绕服务器的实际包装 update_many编号 :
delete_many. RPC运输确实有一个真正的批量终点(POST /rpc/batch不过
createCratestackRpcDataProvider 故意不在这里使用,看
RPC 运输 原因(每框架 If-Match 在批量请求中无法表示).
所以这三种方法在两种运输上都有作用,但是没有解剖性,而且代价是N请求
而不是一个.
程序(custom(中文(简体) )
一个箱子 procedure 没有其他家在一个 DataProvider通过 a procedures 地图到
createCratestackDataProvider'(或 createCratestackRpcDataProvider's) 第二个参数和调用
它通过精炼 custom - 两个供应商的形状相同:
const dataProvider = createCratestackDataProvider(resources, {
procedures: { publishPost: (args) => client.procedures.publishPost(args as never) },
});
await dataProvider.custom!({
url: "",
method: "post",
meta: { procedure: "publishPost" },
payload: { args: { postId: 1 } },
});
范围
超越范围
liveProvider——生成的TypeScript客户端今天没有SSE消费者(没有)EventSource在任何地方crates/cratestack-client-typescript/templates/),尽管服务器有真实的 订阅端点 。 首先需要一个TS SSE客户端. 适用于两种运输方式.authProvider——与数据访问分开的正统关切. 适用于两种运输方式.- 剪接 RPC 写道 —— 说
createCratestackRpcDataProvider从不打电话POST /rpc/batch连 尽管RPC的运输有一个。 每个框架If-Match信头不能用一个字来表示 批量请求,以及此软件包@version保证不是它会默默地削弱的东西 获得原子学——见 RPC 运输。 。 。 . - 皇家警察局
where编号 :or过滤表达式 DSL,以及fields编号 :include编号 :includeFields预测 —— 说CratestackRpcListQuery铁丝网上所有这些都支持 但精细的CrudFilters编号 :Sort形状上没有映射到它们( refine 没有“ raw 服务器过滤器表达式” 或 "关系投影"概念,因此这个提供者从不给他们写信. 来电者可以 想要达到过去精炼的抽象:呼叫config.api.list({ where: "..." })直接说.
本套件继承了已知的、先前存在的缺口,而不是原因: 线路压制
(cratestack#514)没有执行,所以政策被否定 create编号 :update编号 :delete 仍然生成一个
面向工作的客户方法—— config.api.create 仅证明模式声明
有点 @@allow("create", ...),不是说现在的打电话者满足了它。 精细 <Create>
按钮连接到此资源 403{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}在为一个无法做到的打电话者提交申请
创建一个。 直到514号船,在精炼的门 resources 配置
(单位:千美元)create: false编号 :edit: false编号 :delete: false)每个呼叫者角色,不在本包的方法上
存在.
见 guides/refine-integration.md 内
盒装文件 手电线版本
包括上面每个设计选择背后的全部推理.