十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Strapi 如何通过 REST API 调整关联项顺序(connect position 与 disconnect)?

Strapi 如何通过 REST API 调整关联项顺序(connect position 与 disconnect)? Strapi 如何通过 REST API 调整关联项顺序connect position 与 disconnect【免费下载链接】strapi Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.项目地址: https://gitcode.com/GitHub_Trending/st/strapi当你的内容类型里存在一对多、多对多这类列表型关联字段时关联项的排列顺序本身是有意义的比如导航栏、轮播位、排序列表。Strapi 的数据库层对这类关联提供了可排序能力你可以把某一项移动到指定位置之前、之后、列表开头或结尾也可以在同一次请求里移除不需要的项。文档说明这一重排reordering功能同时可用在 Content Manager 和 API 中见 reordering.md。本文只走 RESTContent API这条路说明请求体怎么写、哪些关联支持排序、顺序如何存储、结果怎么验证以及测试中覆盖到的报错边界。适用前提均来自仓库文档与 API 测试关联字段必须是 many 型关系oneToMany / manyToMany / 单向的 has-many。one-to-one 关系每对只有一条关联没有顺序可言polymorphic多态关系明确不存储 order 值文档原话too complicated to implement。请求走 Content API/api前缀下的资源路由并携带Authorization: Bearer token头。仓库 API 测试框架就是按这个方式访问的CONTENT_API_URL_PREFIX /api见 request.js。顺序在数据库里怎么存先理解存储方式才能理解position参数为什么是相对位置而不是序号关联的顺序值存在order字段中双向关系还会把另一侧的顺序存在inverse_order字段中如 m2m 的category_order/address_order成对出现。单向关系只有一侧有 order 字段如 restaurant has many categories只有category_order没有restaurant_order。排序算法采用 fractional indexing分数索引用小数作为顺序值。文档给出了一组示例同一顺序值发生碰撞时会被重算去重例如[ {id: 5, order: 1.5}, {id: 3, order: 1.5} ]→[ {id: 5, order: 1.33}, {id: 3, order: 1.66} ]文档示例非固定预期值。算法要点摘自 reordering.md 的 Algorithm stepsconnect数组被顺序处理每一项按before/after引用的现有关联计算新的 order 值放到开头时 order 记为 0.5。如果before/after引用的 id不在当前关联列表中直接抛错。同一个 id 在数组里重复出现时先前的那条会被移除即重新 connect 已存在的关联等价于把它移动到新位置。disconnect数组处理的是删除从数据库删掉这些关联然后基于剩余项的位置ROW_NUMBER()重排顺序。顺序计算的具体实现在 relations-orderer.ts其类型定义为position?: { before?: ID; after?: ID; start?: true; end?: true }。请求怎么写connect position 与 disconnect更新走标准的内容 API 路由PUT /api/pluralName/documentId仓库测试 relations.test.api.ts 中的updateEntry即以PUT /shops/${documentId}方式调用。请求体中关联字段不再直接传 id 数组而是分成connect与disconnect两个数组——这与 Content Manager 文档对 API 契约的描述一致04-relations.mdxThe API to update the entity expects relations to be categorised into two groups, aconnectarray anddisconnectarray。字段项支持两种 id 写法测试中两套模式都跑{ id: 3 }数据库自增 id{ documentId: 67a9f5f614f101002287e7d5 }文档 id 字符串。注意纯字符串数组如[docId1, docId2]不能携带 position——测试文件中的注释明确写着 reordering only works with objects。要重排就必须用对象形式。基础示例把一项移动到另一项之前假设 shop 的products_mw字段当前按[A, B, C]有序id 分别对应docid1、docid2、docid3为仓库测试 fixture 用的值实际使用请替换为你自己内容类型的字段名和文档 id。把 A 移动到 C 之前curl -X PUT strapi-host/api/shops/shopDocumentId?populateproducts_mw \ -H Authorization: Bearer token \ -H Content-Type: application/json \ -d { data: { products_mw: { connect: [ { documentId: docid-A, position: { before: docid-C } } ] } } }其中strapi-host是你部署 Strapi 的地址token是访问内容 API 的 Bearer tokenshopDocumentId是被更新实体的 documentIddocid-A/docid-C是关联项的 documentId。shopDocumentId与关联项 id 都可以从带?populateproducts_mw的查询响应中取得见下文验证部分。四种位置参数的语义均出自 reordering.md 的负载示例与算法说明position 写法含义{ before: id }放到 id 指定的关联之前{ after: id }放到 id 指定的关联之后{ start: true }放到列表开头order 记为 0.5{ end: true }放到列表结尾移动已经在列表里的项就是重新 connect 它并给出新位置不需要先 disconnect。一次移动多项connect数组可以包含多个项按数组顺序依次计算。仓库 API 测试里的一个用例初始[docid1, docid2, docid3]请求{ data: { products_mw: { connect: [ { documentId: docid-1, position: { end: true } }, { documentId: docid-3, position: { start: true } }, { documentId: docid-2, position: { after: docid-1 } } ] } } }测试断言最终顺序为[docid3, docid1, docid2]见 content-manager 侧测试 Reorder multiple relations。可见数组内元素的先后引用关系会被框架自动整理当某项的位置依赖数组里另一项的新位置时relations-orderer.ts 的sortConnectArray会先把 connect 数组重排成可计算的顺序其头注释举的例子{ id: 5, position: { before: 1 } }必须先等id 1定位完成你不必手工排好依赖顺序。同一次请求里 connect 和 disconnect 一起用两个数组可以放在同一个字段对象里。测试 Reorder a relation before one that is disconnected in the same call 的场景初始[id1, id2, id3]请求{ data: { products_mw: { connect: [ { id: 2, position: { before: 1 } } ], disconnect: [ { id: 1 } ] } } }即把 id2 移到 id1 之前的同时删掉 id1。测试断言最终为[id2, id3]且不会因 id1 既是 disconnect 目标又是位置参照而崩溃。另有一个值得知道的边界测试 Does not delete a relation that is reconnected with position metadata如果同一请求里某项既出现在disconnect又带 position 出现在connect它不会被删除而是被移到 position 指定的位置该用例断言最终顺序为[id1, id3, id2]。验证结果仓库 API 测试的验证方式可以直接照搬到手工操作更新请求带上?populate字段名响应data中的关联数组就是数据库里存储的顺序测试正是对这些数组的顺序做断言。例如 Reorder single relation 用例初始[id1, id2, id3]请求connect: [{ id: id1, position: { before: id3 } }]后测试断言顺序变为[id2, id1, id3]测试代码。新建实体同理POST /api/shops时带上?populateproducts_mw响应里即可看到按 position 计算出的顺序如两个{ start: true }项会形成后进在前的[docid2, docid1]两个{ end: true }项则保持[docid1, docid2]均为测试断言值可作示例参考而非固定预期。报错与边界以下现象均能在仓库源码或测试中找到依据遇到时按对应条件排查before/after引用了不在当前关联列表中的 id默认情况下请求失败测试断言返回 400Rejects strict reorder before a non-related id...。如果确实要容忍非法引用在该字段对象上传options: { strict: false }同一请求即可成功返回测试 Invalid reorder with non-strict mode should not give an error。注意文档对strict的默认取值没有展开说明这里只按测试行为描述。同一个 id 在一次 connect 里重复连接抛InvalidRelationError消息为The relation with id id is already connected. You cannot connect the same relation twice.relations-orderer.ts测试 Update relations using the same id multiple times 断言该场景返回 400ValidationError。connect 数组内出现循环引用A 在 B 之前、B 又在 A 之前抛InvalidRelationError消息为A circular reference was found in the connect array. ...。one-to-one 与 polymorphic 关系不存储 order 值position 排序对它们不适用reordering.md。polymorphic 测试中出现的position: end/__type组合属于多态关联的 connect 用法与本文的顺序调整不是一回事。纯 id 数组不能重排[docId1, docId2]这种写法只用于普通的 connect/disconnect要重排必须升级为带position的对象。更多细节可继续读重排算法图解reordering-algo-2.png 见原文档、connect 数组排序逻辑的单元测试 sort-connect-array.test.ts以及 Content Manager 前端如何 diff 出 connect/disconnect 的说明04-relations.mdx Cleaning data to be posted to the API 一节。【免费下载链接】strapi Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.项目地址: https://gitcode.com/GitHub_Trending/st/strapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表