Repository navigation
[ADR] 声明式端点路由归属与通道分工:命名空间制 + actions/apis 按调用方分工 + type: flow 保留(起草,预计编号 0120) #5060
Description
维护者 2026-08-04 已裁决三项(经执行器车道 PM 的对比分析,含主流平台调研;本 issue 正文即裁决的持久记录),需起草 ADR 落档。docs-only PR,不改任何代码或 schema —— 执行体(publish 门、describe 文案)由 #5040 的 E 系列与 E7 翻转 PR 按本 ADR 实施。
三项裁决
① 命名空间制(否决「任意路由」)
声明式端点(apis: / ApiEndpointSchema.path)不得认领任意路由。路径收紧为:
/api/v1/apps/<应用名>/<子路径>
apps 为平台保留的唯一切出段;<应用名> 派生自声明方 stack/app 的规范身份(起草时从 stack.zod.ts 实核可用的身份键),作者只自由命名子路径。publish 期强制。
依据:主流平台零例外 —— Salesforce Apex REST(/services/apexrest/<ns>/…)、ServiceNow Scripted REST(/api/<scope>/<api_id>/…)、MS Dataverse Custom API(纯名字派生)、Shopify App Proxy(/apps/<子路径>)、K8s CRD(group/version/kind 派生),没有一家让应用元数据认领任意路由。收益:#5040 设计 §1 的保留前缀 pin 清单、spec/runtime 双端一致性测试、跨应用撞路径整类问题在构造上消失;URL 自带应用名可反查;AI 需要掌握的平台内部知识归零。时机红利:v17 硬拒(#4936)已清场,17.x 收紧零迁移成本。
② 通道分工:actions = 平台内命令,apis = 平台外集成面
一句话判据(写进 ADR 与两侧 schema describe 的执行项):调用方在平台内(有会话、懂平台方言:UI 按钮、AI/MCP、SDK)→ actions;调用方在平台外(第三方 webhook、合作方系统)→ apis(资源读写 + webhook 接收)。
依据:actions(/actions/:object/:action,POST-only)已具备参数契约(ADR-0104)、权限门(ADR-0066 D4)、HTTP 语义化错误(#3962)、AI/MCP 暴露(ActionAiSchema),是成熟的命令通道;而平台外调用方的三个硬特征(报文形状对方定 → 需 inputMapping 防腐、无平台会话 → 需 authRequired: false + 端点级 rateLimit、URL 是写进对方系统的对外契约 → 需稳定 + OpenAPI)actions 结构上均不满足。行业同构:Salesforce 内部 Invocable Actions / 对外 Apex REST;ServiceNow 内部 UI Action / 对外 Scripted REST。
③ type: flow 保留在 ApiEndpoint,配三条纪律
「URL 触发 flow」是入站集成的第一原语(Zapier/Make/n8n 的 webhook trigger 即此;showcase 自证案例 POST …/inquiries/purge 本身就是 flow 端点),摘除它 = 第三方 webhook 接收没有元数据故事,只剩代码逃生舱,逆北极星。保留,重叠带用三条纪律约束:
- 分工判据(②的一句话)写进 ADR 与
ApiEndpointSchema/ActionType两侧 describe(describe 修改属 spec 车道执行项,ADR 只立规则); - 同管线红线:flow 端点纯委派 automation 服务(与 action 触发同一条
execute+ 身份转发管线,17.x 立项:建设声明式 ApiEndpoint 执行器(挂载 + matchEndpoint + authRequired/cacheTtl/inputMapping/outputMapping 逐键接线) #5040 设计 §4 已立),零语义分叉 —— 保证选错通道只是风格问题,不是行为问题; - 匿名端点防呆门(E7 publish 门执行项):
authRequired: false的端点必须同时声明rateLimit,否则 publish 拒绝并附处方;签名验证(webhook 真实需要)明示为将来词表候选,不在本 ADR 承诺。
ADR 关系与范围
- 扩充 ADR-0076(one route one owner:0076 答「一条路由归谁」,本 ADR 答「谁有资格认领哪片路由」),不取代;
- 落在 ADR-0049 的时序上:v17 响亮拒绝(声明式
apis:(ApiEndpoint)入站面全链路零执行:元数据装载成功、路由从未挂载、matchEndpoint全仓无实现 #4936 裁决)→ 17.x 执行器(17.x 立项:建设声明式 ApiEndpoint 执行器(挂载 + matchEndpoint + authRequired/cacheTtl/inputMapping/outputMapping 逐键接线) #5040)→ 翻转 PR(E7)实施本 ADR 的 publish 门; - 不写实现细节:
matchEndpoint签名、cacheTtl 键形状、兜底 seam 等留在 17.x 立项:建设声明式 ApiEndpoint 执行器(挂载 + matchEndpoint + authRequired/cacheTtl/inputMapping/outputMapping 逐键接线) #5040 设计文档; - Alternatives Considered 需收录 O1(自由路径 + 保留前缀门)与 O3(actions 全面替代 / Dataverse 模式)及两轴分析(项目长远合理性 / 防 AI 写元数据犯错)。
验收
docs/adr/<下一空位编号>-*.md(起草时以 origin/main + 开放 PR 双查确认编号未被占用,预计 0120),头部格式对齐 ADR-0118(状态/日期/关联/执行项/动因);- 状态 Accepted(2026-08-04,维护者裁决),关联 ADR-0049/0076/0066/0104,执行项引 声明式
apis:(ApiEndpoint)入站面全链路零执行:元数据装载成功、路由从未挂载、matchEndpoint全仓无实现 #4936/ApiRegistry/api-registryplugin 只在packages/core/examples/里被装配,无任何真实 composition 挂载 ——ApiEndpointRegistrationSchema因此整面零执行 #4939/17.x 立项:建设声明式 ApiEndpoint 执行器(挂载 + matchEndpoint + authRequired/cacheTtl/inputMapping/outputMapping 逐键接线) #5040(+ E7 届时补); - 是否随带 changeset 按仓内近期 ADR PR 惯例实核(
.changeset/adr-XXXX-*.md有先例); - ⛔ 不改
content/docs/releases/,不改任何.zod.ts/ runtime 代码。
关联:#4936(裁决与实测)、#4939、#5040(设计全文)、#4910(四问依据)、ADR-0076、ADR-0049。
Activity
os-zhuang commentedon Aug 4, 2026
🔒 认领:执行器车道(B 包)—— 维护者指派立单并即刻派发
会话:
session_01EYGdmvWP1ieZSLqvAW6uyd分支:
claude/issue-5060-adr-endpoint-routingWorktree:
objectstack-issue-5060域:落点
docs/adr/**(按域表最近归domain:devx,本单为跨车道认领 —— 维护者直接指派,B 包程序文档;devx 车道 PM 如有异议请说,即让行)文件面:
docs/adr/<下一空位>-*.md(新文件)+ 按仓例可能的.changeset/adr-*-*.md—— 与在飞 #4936 阶段一(代码 + spec 生成物)及 devx 车道在飞(#5017/#4996/#4917)文件面均不相交执行口径:docs-only,三项裁决照 issue 正文落档,不改代码/schema;执行体归 #5040 E 系列与 E7。
Generated by Claude Code
os-zhuang commentedon Aug 4, 2026
✅ 验收通过 —— PR #5064(ADR-0121),待最后一个检查绿后入队
复核实况(非报告自述):diff 恰为 2 个新增文件(
docs/adr/0121-declarative-endpoint-routing-namespace-and-channel-split.md+375、.changeset/adr-0121-endpoint-routing-namespace.md空 frontmatter 符合 ADR PR 先例);三项裁决 D1–D7 落档完整,O1/O3 两轴否决收录,代价如实(URL 变长、apps段终身保留、D3 是指引不是门);地基事实四条全部实核于origin/main@94f7b6a(含 0120 被 PR #5054 占用故取 0121 的编号避让);与 0076/0049/0066/0104/0078/0028 逐份核对无冲突。文档门禁真实输出在案(check-doc-authoring 361 files clean / check-adr-anchors OK / check-nul-bytes OK,共享锁下串行)。开放问题 Q1 的 PM 裁定(按既有规范可决,不升级;维护者可否决):采 A —— 声明
apis:的 stack 必须显式manifest.namespace,不保留deriveNamespaceFromPackageId回落。理由:对外 URL 是写进第三方系统的契约,B 让一次manifest.id重命名静默改写全部对外地址 —— 正是仓规禁止的静默漂移形状;A 的失败面是 publish 期一条带处方的拒绝。记为 #5040 E7 的工作口径,拒绝文案届时按此写。落地安排:CI 仅剩 TypeScript Type Check 在跑(docs-only,其余全绿)。全绿即转 ready 并入合并队列(本 PR 零生成物触碰,无需与主队列 spec 落地链串行)。域外发现 #5063(ADR-0076 状态行失真)已核实成形,留待分诊轮定级。
Generated by Claude Code
docs(adr-0121): 声明式端点的路由归属与通道分工落档 —— 命名空间制 + actions/apis 按调用方分工 + `t…
chore: bump objectui to 82a94170c405
chore: bump objectui to 82a94170c405 (objectstack-ai#9393)
chore(changeset): re-derive the console 82a94170c405 commit attributi…