diff --git a/packages/rest/src/__tests__/unit/router/routing-table.unit.ts b/packages/rest/src/__tests__/unit/router/routing-table.unit.ts index 1950bd4f5ecd..b5b80b933c14 100644 --- a/packages/rest/src/__tests__/unit/router/routing-table.unit.ts +++ b/packages/rest/src/__tests__/unit/router/routing-table.unit.ts @@ -214,6 +214,44 @@ function runTestsWithRouter(router: RestRouter) { expect(route.pathParams).to.containEql({userId: '1', format: 'json'}); }); + it('finds "GET /orders, /orders/{id}, /orders/{orderId}/shipments" endpoints', () => { + class TestController { + @get('/orders/{id}') + async getOrderById(@param.path.number('id') id: number): Promise { + return {id}; + } + @get('/orders') + async findOrders(): Promise { + return []; + } + // A path that overlaps with `/orders/{id}`. Please note a different var + // name is used - `{orderId}` + @get('/orders/{orderId}/shipments') + async getShipmentsForOrder( + @param.path.number('orderId') id: number, + ): Promise { + return []; + } + } + + const table = givenRoutingTable(); + const spec = getControllerSpec(TestController); + table.registerController(spec, TestController); + + const findAndCheckRoute = (url: string, expectedPath: string) => { + let request = givenRequest({ + method: 'get', + url, + }); + const route = table.find(request); + expect(route.path).to.eql(expectedPath); + }; + + findAndCheckRoute('/orders/1', '/orders/{id}'); + findAndCheckRoute('/orders/1/shipments', '/orders/{orderId}/shipments'); + findAndCheckRoute('/orders', '/orders'); + }); + it('throws if router is not found', () => { const table = givenRoutingTable(); diff --git a/packages/rest/src/router/trie.ts b/packages/rest/src/router/trie.ts index 786cd35dd2a2..313185aa6bda 100644 --- a/packages/rest/src/router/trie.ts +++ b/packages/rest/src/router/trie.ts @@ -161,7 +161,7 @@ function search( // There might be multiple matches, such as `/users/{id}` and `/users/{userId}` for (const child of children) { const result = search(keys, index + 1, params, child.node); - if (result) { + if (result && isNodeWithValue(result.node)) { Object.assign(params, child.params); return result; }