fix(rest): register static data-action routes before greedy :object/:id#2315
Merged
Conversation
The REST router (RouteManager → IHttpServer/Express adapter) matches first-registered-wins with no specificity sorting. registerDataActionEndpoints (which holds GET /data/:object/export) ran AFTER registerCrudEndpoints (which holds the greedy GET /data/:object/:id), so a request to `GET /data/<object>/export` was captured by `:object/:id` — "export" treated as a record id — returning 404 RECORD_NOT_FOUND instead of streaming the export. Reorder so the static-literal action routes register before the greedy :object/:id matcher, mirroring the existing /meta/:type/:name/references-before -/meta/:type/:name convention. The reorder is safe in both directions: registerDataActionEndpoints has no greedy 2-segment :object/:id routes, and the only per-method collision in the data namespace is GET export vs GET :id. Add a regression test asserting the export route's registration index precedes the get-by-id route's.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 5 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
REST 路由器(
RouteManager→IHttpServer/Express 适配器)按先注册先匹配(first-match-wins)工作,没有任何按具体性排序的逻辑(见packages/rest/src/route-manager.ts:88,196)。registerDataActionEndpoints(含GET /data/:object/export)在registerCrudEndpoints(含贪婪的GET /data/:object/:id)之后注册,于是请求GET /api/v1/data/<object>/export?format=csv会先撞上:object/:id,"export"被当成一条记录的 id → 返回404 RECORD_NOT_FOUND,根本到不了导出处理器。已对rest@10.0.0实证复现。修复
把
registerDataActionEndpoints(bp)调到registerCrudEndpoints(bp)之前注册,让静态字面量动作路由(/export、/import、/:id/clone等)排在贪婪的:object/:id之前。沿用代码库已有惯例(/meta/:type/:name/references先于/meta/:type/:name,见rest-server.ts:2140)。为什么安全(两个方向都核对过)
按 HTTP 方法 + 段数穷举,first-match 下只有"同方法 + 同段数 + 字面量 vs
:param"才会互相遮蔽::param:object/:idexport抢到:id前 = 修复目标;export只精确匹配/export段,不会反向遮蔽真实 id:object/:id/clone)import/query/batch等全是字面量,任何顺序都精确命中:object/:idregisterDataActionEndpoints里没有任何贪婪 2 段:object/:id路由(只有字面量动作和更深的:id/clone、:id/shares),所以它先注册也吃不掉任何 CRUD 字面量路由。enableCrud=false时行为不变:export 的注册条件没动。测试
GET /export的注册下标必须小于GET /:object/:id。在修复前的顺序下该测试失败(export idx 61不小于:id idx 54),修复后通过。packages/rest全量 136 个测试通过。🤖 Generated with Claude Code