Merge pull request #15302 from backstage/freben/catalog-order

Implement server side ordering in the entities endpoint
This commit is contained in:
Fredrik Adelöw
2022-12-21 13:33:15 +01:00
committed by GitHub
14 changed files with 381 additions and 17 deletions
+12
View File
@@ -161,6 +161,17 @@ export type EntityFilterQuery =
| Record<string, string | symbol | (string | symbol)[]>[]
| Record<string, string | symbol | (string | symbol)[]>;
// @public
export type EntityOrderQuery =
| {
field: string;
order: 'asc' | 'desc';
}
| Array<{
field: string;
order: 'asc' | 'desc';
}>;
// @public
export interface GetEntitiesByRefsRequest {
entityRefs: string[];
@@ -179,6 +190,7 @@ export interface GetEntitiesRequest {
filter?: EntityFilterQuery;
limit?: number;
offset?: number;
order?: EntityOrderQuery;
}
// @public
@@ -193,6 +193,31 @@ describe('CatalogClient', () => {
expect(response.items).toEqual([]);
});
it('handles ordering properly', async () => {
expect.assertions(2);
server.use(
rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => {
expect(req.url.search).toBe(
'?order=asc:kind&order=desc:metadata.name',
);
return res(ctx.json([]));
}),
);
const response = await client.getEntities(
{
order: [
{ field: 'kind', order: 'asc' },
{ field: 'metadata.name', order: 'desc' },
],
},
{ token },
);
expect(response.items).toEqual([]);
});
});
describe('getEntitiesByRefs', () => {
+20 -1
View File
@@ -99,7 +99,14 @@ export class CatalogClient implements CatalogApi {
request?: GetEntitiesRequest,
options?: CatalogRequestOptions,
): Promise<GetEntitiesResponse> {
const { filter = [], fields = [], offset, limit, after } = request ?? {};
const {
filter = [],
fields = [],
order,
offset,
limit,
after,
} = request ?? {};
const params: string[] = [];
// filter param can occur multiple times, for example
@@ -129,6 +136,18 @@ export class CatalogClient implements CatalogApi {
params.push(`fields=${fields.map(encodeURIComponent).join(',')}`);
}
if (order) {
for (const directive of [order].flat()) {
if (directive) {
params.push(
`order=${encodeURIComponent(directive.order)}:${encodeURIComponent(
directive.field,
)}`,
);
}
}
}
if (offset !== undefined) {
params.push(`offset=${offset}`);
}
+46
View File
@@ -98,6 +98,48 @@ export type EntityFilterQuery =
*/
export type EntityFieldsQuery = string[];
/**
* Dot-separated field based ordering directives, controlling the sort order of
* the output entities.
*
* @remarks
*
* Each field is a dot-separated path into an entity's keys. The order is either
* ascending (`asc`, lexicographical order) or descending (`desc`, reverse
* lexicographical order). The ordering is case insensitive.
*
* If more than one order directive is given, later directives have lower
* precedence (they are applied only when directives of higher precedence have
* equal values).
*
* Example:
*
* ```
* [
* { field: 'kind', order: 'asc' },
* { field: 'metadata.name', order: 'desc' },
* ]
* ```
*
* This will order the output first by kind ascending, and then within each kind
* (if there's more than one of a given kind) by their name descending.
*
* When given a field that does NOT exist on all entities in the result set,
* those entities that do not have the field will always be sorted last in that
* particular order step, no matter what the desired order was.
*
* @public
*/
export type EntityOrderQuery =
| {
field: string;
order: 'asc' | 'desc';
}
| Array<{
field: string;
order: 'asc' | 'desc';
}>;
/**
* The request type for {@link CatalogClient.getEntities}.
*
@@ -113,6 +155,10 @@ export interface GetEntitiesRequest {
* declarations.
*/
fields?: EntityFieldsQuery;
/**
*If given, order the result set by those directives.
*/
order?: EntityOrderQuery;
/**
* If given, skips over the first N items in the result set.
*/
@@ -22,6 +22,7 @@ export type {
CatalogRequestOptions,
EntityFieldsQuery,
EntityFilterQuery,
EntityOrderQuery,
GetEntitiesByRefsRequest,
GetEntitiesByRefsResponse,
GetEntitiesRequest,