Skip to content

配置了 api.apiPath 时,rest 的 9 条 direct-mount 路由挂在 {basePath}/{version} 而不是 {apiPath} #6306

Description

@qq9340100

out-of-scope 发现,来自 #5822(PR #6303)的实现过程,按 Prime Directive #10 单独立单。未认领

事实

RestServergetApiBasePath() 决定自己所有路由的前缀:

  • packages/rest/src/rest-server.tsreturn api.apiPath ?? ${''}${'$'}{api.basePath}/${'$'}{api.version}${''};

rest-api-plugin.ts 给两个 direct-mount registrar 算的 base 不读 apiPath:

  • packages/rest/src/rest-api-plugin.tsconst basePath = config.api?.api?.basePath || '/api'; const version = config.api?.api?.version || 'v1'; const versionedBase = ${''}${'$'}{basePath}/${'$'}{version}${''};

apiPath 是 spec 里可声明的公开配置键(packages/spec/src/api/rest-server.zod.ts:
"Full API path (defaults to {basePath}/{version})",并已进 content/docs/references/api/rest-server.mdx)。

后果

部署一旦设置 api.apiPath(例如 /backend/api/v9):

  • CRUD / metadata / reports / … 等全部 route-manager 路由挂在 /backend/api/v9/...;
  • packages.*(4 条)与 datasources/:name/external/*(5 条)仍然挂在 /api/v1/...

即 SDK 的 packages.list / packages.get / packages.uninstall /
datasources.external.* 在该部署上打到 {apiPath}/packages 会 404,真正服务它们的是另一个前缀。
默认配置(不设 apiPath)两者相等,所以今天的 example / showcase 都撞不到 —— 仓库里没有任何
example 设置过 apiPath

#5822 的关系(不是它引入的,但被它照出来)

#5822(PR #6303)让这 9 条对 RestServer.getRoutes() 可枚举。枚举面因此如实显示它们挂在
/api/v1/...;而 {apiPath} 那份 /openapi.json 会按 isUnderBase 把它们过滤掉 ——
文档没有说谎(它们确实不在那个 base 下),但这正好把前缀不一致变成可见现象。PR #6303
刻意没有顺手改前缀:改它会移动 9 条路由的线上 URL,属于独立的、需要评审的行为变更。

复现

defineStack({ /* … */ server: { api: { apiPath: '/backend/api/v9' } } })
// GET /backend/api/v9/data/:object  → 200(route-manager 路由跟随 apiPath)
// GET /backend/api/v9/packages      → 404
// GET /api/v1/packages              → 200(direct-mount 路由没跟随)

可能的处置(留给分诊,不预设)

  1. rest-api-plugin.ts 用与 RestServer.getApiBasePath() 同一个表达式(或直接把这个
    base 从 RestServer 暴露出来,单一真相源),9 条跟随 apiPath —— 行为变更:设置了
    apiPath 的部署上这 9 条 URL 会移动;
  2. 或者裁定 apiPath 只管 route-manager 面,并把这个边界写进 apiPath.describe() 与文档
    —— 但那等于承认一个部署里有两个 API 前缀;
  3. 或者退役 apiPath(ADR-0049 enforce-or-remove 的形状:一个声明了却只被一半路由遵守的键)。

查重

origin/main 与 open issue 各搜过 apiPath / direct-mount / basePath 前缀,无同题单;
#5822 是发现现场(处置面不同,PR #6303 已写明为何不在其中修)。

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions