ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Refine Simple REST 数据提供器实战指南:REST API 集成、URL 约定与源码级定制

2026/9/11 16:12:01 拓冰建站 浏览量
Refine Simple REST 数据提供器实战指南:REST API 集成、URL 约定与源码级定制 Refine Simple REST 数据提供器实战指南REST API 集成、URL 约定与源码级定制【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine本文以 Refine 官方数据提供器refinedev/simple-rest为主线系统讲解如何在 Refine v5 项目中快速接入符合 json-server 设计约定的 REST API覆盖安装、配置、分页/排序/过滤的 Query 序列化、HTTP 方法与自定义 Header并结合仓库源码与单元测试揭示其底层实现原理。读完本文你将能独立完成一个 REST 数据源的接入、调优并在 API 不匹配时通过swizzle命令定制专属数据提供器。Simple REST 是什么refinedev/simple-rest是 Refine 生态中面向标准 REST API 的数据提供器data provider实现。它的 URL 设计与查询参数约定建立在 json-server 的基础之上资源名直接拼在apiUrl之后分页、排序、过滤分别通过_start/_end、_sort/_order、field_operator等约定参数表达并依靠响应头x-total-count返回数据总数。该包导出一个工厂函数dataProvider(apiUrl, httpClient)完整实现了 RefineDataProvider接口中的核心方法包括getList、getMany、getOne、create、update、deleteOne以及custom和getApiUrl。它的定位是开箱即用、按需定制先用它快速跑通数据流当后端 API 不遵循标准设计时再基于它做局部或整体定制。从仓库的 packages/simple-rest/package.json 可以看到该包当前版本为6.0.1运行时依赖仅axios与query-string以refinedev/core^5.0.0作为 peer dependency并要求 Node.js 20。安装在项目根目录执行npm install refinedev/simple-rest # 或使用 pnpm pnpm add refinedev/simple-rest安装后数据提供器即作为dataProvider属性接入Refine组件。快速开始dataProvider工厂函数接受两个参数apiUrl必填API 的基础地址所有请求都会拼接到该地址之下httpClient可选自定义 axios 实例用于在请求层统一处理认证、错误拦截、Token 刷新等逻辑不传时使用包内置的默认实例。import { Refine } from refinedev/core; import dataProvider from refinedev/simple-rest; import axios from axios; // 自定义 axios 实例可选可用于注入认证头、统一错误处理 const httpClient axios.create(); const App () { return ( Refine // httpClient 为可选参数不传则使用内置实例 dataProvider{dataProvider(https://api.fake-rest.refine.dev, httpClient)} /* ... */ / ); };注意这里传给Refine的是dataProvider(...)的调用结果一个方法对象而不是函数本身apiUrl需替换为你自己的后端地址。URL 设计约定数据提供器的每个方法都按标准 REST 风格构造 URL下表来自官方文档 documentation/docs/data/packages/simple-rest/index.md可直接作为后端路由设计对照MethodURLQuery ParametersBodygetListapiUrl/resourcepagination,sorters,filtersgetOneapiUrl/resource/idgetManyapiUrl/resourceidcreateapiUrl/resourcevariablesupdateapiUrl/resource/idvariablesdeleteOneapiUrl/resource/iddata: variables以apiUrl https://api.fake-rest.refine.dev、资源posts为例getList请求GET /postsgetOne、update、deleteOne请求GET/PATCH/DELETE /posts/1getMany请求GET /posts?id1id2ids 数组被query-string序列化为重复的id参数create请求POST /posts请求体携带variablesdeleteOne的请求体通过 axios 配置的data字段携带variables详见下文源码解析。分页、排序与过滤Query 序列化源码解析getList是逻辑最复杂的方法其 URL 的构建逻辑集中在 packages/simple-rest/src/provider.ts分页、排序、过滤最终都会落到 URL 的查询参数上。分页_start与_end从源码看getList对pagination的解构默认值为currentPage 1、pageSize 10、mode server。当mode server默认值时query._start (currentPage - 1) * pageSize; query._end currentPage * pageSize;即第 1 页请求?_start0_end10第 2 页请求?_start10_end20。如果传pagination: { mode: off }则不分页不追加这两个参数。测试 packages/simple-rest/test/getList/index.spec.ts 还专门验证了当过滤、排序、分页都为空时请求 URL 上不会出现多余的?字符。排序_sort与_order排序由 packages/simple-rest/src/utils/generateSort.ts 生成把多个排序字段分别用逗号拼接进_sort与_order。例如对id升序、title降序排序会得到?_sortid,title_orderasc,desc。当sorters为空时该函数返回undefinedgetList不会追加排序参数。过滤操作符映射过滤条件由 packages/simple-rest/src/utils/generateFilter.ts 与 packages/simple-rest/src/utils/mapOperator.ts 配合生成。mapOperator把 Refine 的逻辑操作符映射为 json-server 风格的后缀Refine 操作符序列化后的查询参数后缀说明eq无后缀直接以字段名作为参数ne_ne不等于gte_gte大于等于lte_lte小于等于contains_like模糊匹配其他操作符无后缀按字段名直接传值例如过滤category.id 1最终请求为GET /posts?category.id1status ne draft则序列化为status_nedraft。其余操作符gt、lt、in、between、null、startswith等在mapOperator中均返回空字符串直接以fieldvalue形式传递——这是简单 REST的取舍只承诺最常见的操作符映射特殊需求交给custom方法或 swizzle 定制。generateFilter还有两个值得注意的行为field q的过滤条件被原样保留为q参数用于全文搜索场景operator为or或and时会直接抛出错误提示不支持该操作符可创建自定义数据提供器。这意味着 Simple REST 默认不支持逻辑组过滤需要该能力时应考虑定制。总数x-total-count响应头getList返回的total来自响应头x-total-countheaders[x-total-count]强制转为数字当该头缺失时回退为data.length。因此后端需要在响应头中返回真实总数前端才能正确渲染分页。custom 方法custom方法用于调用非标准端点其实现packages/simple-rest/src/provider.ts会把传入的sorters、filters、query依次序列化拼接进 URL并根据method选择请求方式put/post/patch携带 payload 体delete通过 axios 的data配置携带 payload其余情况默认走GET。默认 HTTP 方法与自定义每个数据提供器方法默认使用如下 HTTP 方法MethodHTTP MethodgetListGETgetOneGETgetManyGETcreatePOSTupdatePATCHdeleteOneDELETE注意update默认是PATCH部分更新而非PUT整体替换这符合 json-server 的设计习惯。如果后端要求某个方法使用不同动词无需改源码只需在调用 hook 时通过meta.method覆盖import { useUpdate } from refinedev/core; const { mutate } useUpdate(); mutate({ resource: posts, id: 1, values: { title: New title, }, meta: { method: put, }, });从源码看meta.method的值被分为两类getList/getMany/getOne限定为get | delete | head | optionscreate/update/deleteOne限定为post | put | patch。也就是说如果你为update传入meta.method: put请求会变为PUT /posts/1body 携带variables。传递自定义 Header部分接口需要在单次请求级别附加认证或业务头可以通过meta.headers传入它会透传给 axios 请求配置import { useOne } from refinedev/core; useOne({ resource: posts, id: 1, meta: { headers: { X-Custom-Header: Custom header value, }, }, });headers只作用于本次调用适合临时性的跨租户标识、调试头等场景全局性的认证头更推荐在自定义httpClient的拦截器里统一注入。错误处理与默认 axios 实例Simple REST 内置了一个默认 axios 实例实现在 packages/simple-rest/src/utils/axios.ts 中。它在响应拦截器的错误分支里把原始错误规整为 Refine 的HttpError结构const customError: HttpError { ...error, message: error.response?.data?.message, statusCode: error.response?.status, };即从响应体提取message、从响应对象提取statusCode统一 reject 出去方便 Refine 的useShow、useForm等 hook 展示错误信息。当你的后端错误结构不同比如 message 字段在error对象里或需要携带 Authorization 头时就应传入自定义httpClientimport axios from axios; const httpClient axios.create({ baseURL: https://api.example.com, headers: { Authorization: Bearer ${token} }, }); httpClient.interceptors.response.use( (response) response, (error) { // 统一错误映射、401 跳转登录等 return Promise.reject(error); }, );用 swizzle 定制数据提供器当后端 REST API 偏离 simple-rest 的约定例如分页用page/limit、过滤用其他参数名时官方推荐用 Refine CLI 的swizzle命令把数据提供器源码复制到项目内自行修改在项目目录运行npm run refine swizzle从列表中选择refinedev/simple-rest编辑生成在项目中的rest-data-provider/index.ts按需修改getList的分页参数、mapOperator的操作符映射等将定制后的数据提供器传给Refineimport { Refine } from refinedev/core; import { dataProvider } from ./rest-data-provider; const App () { return ( Refine dataProvider{dataProvider(https://api.fake-rest.refine.dev)} /* ... */ / ); };swizzle 出来的rest-data-provider保留了provider.ts的完整结构你可以在复制品上直接改_start/_end的拼法、替换query-string序列化逻辑而无需修改 node_modules 中的包文件。仓库内 packages/simple-rest/src/provider.ts、packages/simple-rest/src/utils/generateFilter.ts、packages/simple-rest/src/utils/mapOperator.ts 就是最直接的定制参考模板。测试验证约定即契约仓库为 Simple REST 配备了完整的 vitest 测试packages/simple-rest/test既是回归保障也是行为契约文档packages/simple-rest/test/getList/index.spec.ts 验证了getList对https://api.fake-rest.refine.dev的请求默认分页返回total为 1000带category.id 1过滤时返回 17 条排序、过滤组合生效空条件下 URL 不带?packages/simple-rest/test/utils/mapOperator.spec.ts 覆盖了ne、gte、lte、contains等映射结果并断言其他操作符含and/or/between/null/startswith等均返回空字符串——这进一步印证了只承诺常见操作符的设计边界此外还有create、update、deleteOne、getOne、custom等目录下的 mock 与 spec展示了每个方法在api.fake-rest.refine.dev上的实际请求形态与响应解析。小结refinedev/simple-rest的价值在于标准约定 低成本定制对符合 json-server 风格的后端一个工厂函数调用即可完成全部 CRUD 接入分页、排序、过滤的参数化全部由 provider.ts 与 utils 透明处理meta.method/meta.headers提供按请求的灵活性遇到不匹配的 APIswizzle命令让你把实现复制进项目自由改造。接入前建议先对照本文的 URL 与参数约定表核对后端路由再用 测试用例 中的请求形态作为联调基线可以显著缩短集成周期。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考