diff --git a/packages/rest/src/rest-server.ts b/packages/rest/src/rest-server.ts index 2bc9e253f1..8eff0c4941 100644 --- a/packages/rest/src/rest-server.ts +++ b/packages/rest/src/rest-server.ts @@ -216,10 +216,7 @@ export class RestServer { * Register discovery endpoints */ private registerDiscoveryEndpoints(basePath: string): void { - this.routeManager.register({ - method: 'GET', - path: basePath, - handler: async (_req: any, res: any) => { + const discoveryHandler = async (_req: any, res: any) => { try { const discovery = await this.protocol.getDiscovery(); @@ -250,7 +247,24 @@ export class RestServer { } catch (error: any) { res.status(500).json({ error: error.message }); } + }; + + // Register at basePath (e.g. /api/v1) + this.routeManager.register({ + method: 'GET', + path: basePath, + handler: discoveryHandler, + metadata: { + summary: 'Get API discovery information', + tags: ['discovery'], }, + }); + + // Register at basePath/discovery (e.g. /api/v1/discovery) + this.routeManager.register({ + method: 'GET', + path: `${basePath}/discovery`, + handler: discoveryHandler, metadata: { summary: 'Get API discovery information', tags: ['discovery'], diff --git a/packages/rest/src/rest.test.ts b/packages/rest/src/rest.test.ts index 47233493c0..89a407ebdc 100644 --- a/packages/rest/src/rest.test.ts +++ b/packages/rest/src/rest.test.ts @@ -309,8 +309,9 @@ describe('RestServer', () => { // Expect at least discovery + metadata + CRUD routes const paths = routes.map((r) => r.path); - // Discovery + // Discovery (both basePath and basePath/discovery) expect(paths).toContain('/api/v1'); + expect(paths).toContain('/api/v1/discovery'); // Metadata expect(paths.some((p) => p.includes('/meta'))).toBe(true); // CRUD @@ -356,7 +357,7 @@ describe('RestServer', () => { rest.registerRoutes(); const routes = rest.getRoutes(); - // Discovery route is the basePath itself (e.g. /api/v1) + // Neither basePath nor basePath/discovery should be registered const discoveryRoutes = routes.filter((r) => r.metadata?.tags?.includes('discovery'), ); diff --git a/packages/runtime/src/dispatcher-plugin.ts b/packages/runtime/src/dispatcher-plugin.ts index 70380b6e9a..0a9e780ec5 100644 --- a/packages/runtime/src/dispatcher-plugin.ts +++ b/packages/runtime/src/dispatcher-plugin.ts @@ -91,6 +91,11 @@ export function createDispatcherPlugin(config: DispatcherPluginConfig = {}): Plu res.json({ data: dispatcher.getDiscoveryInfo(prefix) }); }); + // ── Discovery (versioned API path) ────────────────────────── + server.get(`${prefix}/discovery`, async (_req: any, res: any) => { + res.json({ data: dispatcher.getDiscoveryInfo(prefix) }); + }); + // ── Auth ──────────────────────────────────────────────────── server.post(`${prefix}/auth/login`, async (req: any, res: any) => { try {