Skip to content

[ADR] 声明式端点路由归属与通道分工:命名空间制 + actions/apis 按调用方分工 + type: flow 保留(起草,预计编号 0120) #5060

Closed

Description

@os-zhuang

维护者 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 接收没有元数据故事,只剩代码逃生舱,逆北极星。保留,重叠带用三条纪律约束:

  1. 分工判据(②的一句话)写进 ADR 与 ApiEndpointSchema/ActionType 两侧 describe(describe 修改属 spec 车道执行项,ADR 只立规则);
  2. 同管线红线:flow 端点纯委派 automation 服务(与 action 触发同一条 execute + 身份转发管线,17.x 立项:建设声明式 ApiEndpoint 执行器(挂载 + matchEndpoint + authRequired/cacheTtl/inputMapping/outputMapping 逐键接线) #5040 设计 §4 已立),零语义分叉 —— 保证选错通道只是风格问题,不是行为问题;
  3. 匿名端点防呆门(E7 publish 门执行项):authRequired: false 的端点必须同时声明 rateLimit,否则 publish 拒绝并附处方;签名验证(webhook 真实需要)明示为将来词表候选,不在本 ADR 承诺。

ADR 关系与范围

验收

关联:#4936(裁决与实测)、#4939、#5040(设计全文)、#4910(四问依据)、ADR-0076、ADR-0049。

Activity

  1. self-assigned this
    on Aug 4, 2026
  2. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    🔒 认领:执行器车道(B 包)—— 维护者指派立单并即刻派发
    会话:session_01EYGdmvWP1ieZSLqvAW6uyd
    分支:claude/issue-5060-adr-endpoint-routing
    Worktree: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

  3. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    ✅ 验收通过 —— 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

  4. added a commit that references this issue on Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions