diff --git a/.changeset/silly-suits-run.md b/.changeset/silly-suits-run.md index ed0961a584..812e6ee933 100644 --- a/.changeset/silly-suits-run.md +++ b/.changeset/silly-suits-run.md @@ -3,6 +3,6 @@ '@backstage/plugin-catalog-backend': minor --- -Add /v2beta1/entities endpoint returning paginated entities. +Add /v2/entities endpoint returning paginated entities. The endpoint supports cursor base pagination and server side sorting of the entities by name or uid. diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index ed27bb0016..9dc60da193 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -300,7 +300,7 @@ describe('CatalogClient', () => { beforeEach(() => { server.use( - rest.get(`${mockBaseUrl}/v2beta1/entities`, (_, res, ctx) => { + rest.get(`${mockBaseUrl}/v2/entities`, (_, res, ctx) => { return res(ctx.json(defaultServiceResponse)); }), ); @@ -321,7 +321,7 @@ describe('CatalogClient', () => { res(ctx.json({ entities: [], totalItems: 0 })), ); - server.use(rest.get(`${mockBaseUrl}/v2beta1/entities`, mockedEndpoint)); + server.use(rest.get(`${mockBaseUrl}/v2/entities`, mockedEndpoint)); const response = await client.getPaginatedEntities?.( { @@ -356,7 +356,7 @@ describe('CatalogClient', () => { res(ctx.json({ entities: [], totalItems: 0 })), ); - server.use(rest.get(`${mockBaseUrl}/v2beta1/entities`, mockedEndpoint)); + server.use(rest.get(`${mockBaseUrl}/v2/entities`, mockedEndpoint)); await client.getPaginatedEntities?.({ fields: ['a', 'b'], @@ -379,7 +379,7 @@ describe('CatalogClient', () => { res(ctx.json({ entities: [], totalItems: 0 })), ); - server.use(rest.get(`${mockBaseUrl}/v2beta1/entities`, mockedEndpoint)); + server.use(rest.get(`${mockBaseUrl}/v2/entities`, mockedEndpoint)); await client.getPaginatedEntities?.({ fields: ['a', 'b'], @@ -422,7 +422,7 @@ describe('CatalogClient', () => { ), ); - server.use(rest.get(`${mockBaseUrl}/v2beta1/entities`, mockedEndpoint)); + server.use(rest.get(`${mockBaseUrl}/v2/entities`, mockedEndpoint)); const response = await client.getPaginatedEntities?.({ limit: 2, diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 52ed2fd8fc..8af2a40ccd 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -251,7 +251,7 @@ export class CatalogClient implements CatalogApi { totalItems: number; nextCursor?: string; prevCursor?: string; - }>('GET', `/v2beta1/entities${query}`, options); + }>('GET', `/v2/entities${query}`, options); } /** diff --git a/plugins/catalog-backend/src/service/createRouter.test.ts b/plugins/catalog-backend/src/service/createRouter.test.ts index c3b96fbfd8..0fe32c02b1 100644 --- a/plugins/catalog-backend/src/service/createRouter.test.ts +++ b/plugins/catalog-backend/src/service/createRouter.test.ts @@ -136,7 +136,7 @@ describe('createRouter readonly disabled', () => { }); }); - describe('GET /v2beta1/entities', () => { + describe('GET /v2/entities', () => { it('happy path: lists entities', async () => { const entities: Entity[] = [ { apiVersion: 'a', kind: 'b', metadata: { name: 'n' } }, @@ -148,7 +148,7 @@ describe('createRouter readonly disabled', () => { nextCursor: 'something', }); - const response = await request(app).get('/v2beta1/entities'); + const response = await request(app).get('/v2/entities'); expect(response.status).toEqual(200); expect(response.body).toEqual({ entities, @@ -163,7 +163,7 @@ describe('createRouter readonly disabled', () => { totalItems: 0, }); const response = await request(app).get( - '/v2beta1/entities?filter=a=1,a=2,b=3&filter=c=4&sortField=metadata.name,asc&sortField=metadata.uid,desc', + '/v2/entities?filter=a=1,a=2,b=3&filter=c=4&sortField=metadata.name,asc&sortField=metadata.uid,desc', ); expect(response.status).toEqual(200); @@ -198,9 +198,7 @@ describe('createRouter readonly disabled', () => { nextCursor: 'next', }); - const response = await request(app).get( - '/v2beta1/entities?cursor=something', - ); + const response = await request(app).get('/v2/entities?cursor=something'); expect(entitiesCatalog.paginatedEntities).toHaveBeenCalledTimes(1); expect(entitiesCatalog.paginatedEntities).toHaveBeenCalledWith({ cursor: 'something', diff --git a/plugins/catalog-backend/src/service/createRouter.ts b/plugins/catalog-backend/src/service/createRouter.ts index a7f5373a03..c4c2c87bad 100644 --- a/plugins/catalog-backend/src/service/createRouter.ts +++ b/plugins/catalog-backend/src/service/createRouter.ts @@ -131,7 +131,7 @@ export async function createRouter( // TODO(freben): encode the pageInfo in the response res.json(entities); }) - .get('/v2beta1/entities', async (req, res) => { + .get('/v2/entities', async (req, res) => { const response = await entitiesCatalog.paginatedEntities({ ...parsePaginatedEntitiesParams(req.query), authorizationToken: getBearerToken(req.header('authorization')),