Api docs remove Relations from Post & Patch (#5817)

* Remove relations where they cannot be used
* Removed duplicated schema for findMany
* Reuse schema for Relation variant to reduce size of sent json object

closes #5778

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: martmull <martmull@hotmail.fr>
This commit is contained in:
brendanlaschke
2024-06-11 15:31:48 +02:00
committed by GitHub
parent 58fb86f2c3
commit 4994a9c3a9
5 changed files with 114 additions and 56 deletions

View File

@ -102,12 +102,6 @@ describe('computeSchemaComponents', () => {
type: 'string', type: 'string',
enum: ['OPTION_1', 'OPTION_2'], enum: ['OPTION_1', 'OPTION_2'],
}, },
fieldRelation: {
type: 'array',
items: {
$ref: '#/components/schemas/ToObjectMetadataName',
},
},
fieldPosition: { fieldPosition: {
type: 'number', type: 'number',
}, },
@ -145,16 +139,28 @@ describe('computeSchemaComponents', () => {
}, },
}, },
}, },
ObjectsName: { 'ObjectName with Relations': {
description: 'A list of objectsName', allOf: [
{
$ref: '#/components/schemas/ObjectName',
},
{
properties: {
fieldRelation: {
type: 'array',
items: {
$ref: '#/components/schemas/ToObjectMetadataName',
},
},
},
type: 'object',
},
],
description: undefined,
example: { example: {
fieldNumber: '', fieldNumber: '',
}, },
items: {
$ref: '#/components/schemas/ObjectName',
},
required: ['fieldNumber'], required: ['fieldNumber'],
type: 'array',
}, },
}); });
}); });

View File

@ -51,6 +51,10 @@ const getSchemaComponentsProperties = (
item: ObjectMetadataEntity, item: ObjectMetadataEntity,
): Properties => { ): Properties => {
return item.fields.reduce((node, field) => { return item.fields.reduce((node, field) => {
if (field.type == FieldMetadataType.RELATION) {
return node;
}
let itemProperty = {} as Property; let itemProperty = {} as Property;
switch (field.type) { switch (field.type) {
@ -61,18 +65,6 @@ const getSchemaComponentsProperties = (
enum: field.options.map((option: { value: string }) => option.value), enum: field.options.map((option: { value: string }) => option.value),
}; };
break; break;
case FieldMetadataType.RELATION:
if (field.fromRelationMetadata?.toObjectMetadata.nameSingular) {
itemProperty = {
type: 'array',
items: {
$ref: `#/components/schemas/${capitalize(
field.fromRelationMetadata?.toObjectMetadata.nameSingular || '',
)}`,
},
};
}
break;
case FieldMetadataType.LINK: case FieldMetadataType.LINK:
case FieldMetadataType.LINKS: case FieldMetadataType.LINKS:
case FieldMetadataType.CURRENCY: case FieldMetadataType.CURRENCY:
@ -106,6 +98,37 @@ const getSchemaComponentsProperties = (
}, {} as Properties); }, {} as Properties);
}; };
const getSchemaComponentsRelationProperties = (
item: ObjectMetadataEntity,
): Properties => {
return item.fields.reduce((node, field) => {
let itemProperty = {} as Property;
if (field.type == FieldMetadataType.RELATION) {
if (field.fromRelationMetadata?.toObjectMetadata.nameSingular) {
itemProperty = {
type: 'array',
items: {
$ref: `#/components/schemas/${capitalize(
field.fromRelationMetadata?.toObjectMetadata.nameSingular || '',
)}`,
},
};
}
}
if (field.description) {
itemProperty.description = field.description;
}
if (Object.keys(itemProperty).length) {
node[field.name] = itemProperty;
}
return node;
}, {} as Properties);
};
const getRequiredFields = (item: ObjectMetadataEntity): string[] => { const getRequiredFields = (item: ObjectMetadataEntity): string[] => {
return item.fields.reduce((required, field) => { return item.fields.reduce((required, field) => {
if (!field.isNullable && field.defaultValue === null) { if (!field.isNullable && field.defaultValue === null) {
@ -118,33 +141,6 @@ const getRequiredFields = (item: ObjectMetadataEntity): string[] => {
}, [] as string[]); }, [] as string[]);
}; };
const computeBatchSchemaComponent = (
item: ObjectMetadataEntity,
): OpenAPIV3_1.SchemaObject => {
const result = {
type: 'array',
description: `A list of ${item.namePlural}`,
items: { $ref: `#/components/schemas/${capitalize(item.nameSingular)}` },
example: [{}],
} as OpenAPIV3_1.SchemaObject;
const requiredFields = getRequiredFields(item);
if (requiredFields?.length) {
result.required = requiredFields;
result.example = requiredFields.reduce(
(example, requiredField) => {
example[requiredField] = '';
return example;
},
{} as Record<string, string>,
);
}
return result;
};
const computeSchemaComponent = ( const computeSchemaComponent = (
item: ObjectMetadataEntity, item: ObjectMetadataEntity,
): OpenAPIV3_1.SchemaObject => { ): OpenAPIV3_1.SchemaObject => {
@ -172,13 +168,48 @@ const computeSchemaComponent = (
return result; return result;
}; };
const computeRelationSchemaComponent = (
item: ObjectMetadataEntity,
): OpenAPIV3_1.SchemaObject => {
const result = {
description: item.description,
allOf: [
{
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
},
{
type: 'object',
properties: getSchemaComponentsRelationProperties(item),
},
],
example: {},
} as OpenAPIV3_1.SchemaObject;
const requiredFields = getRequiredFields(item);
if (requiredFields?.length) {
result.required = requiredFields;
result.example = requiredFields.reduce(
(example, requiredField) => {
example[requiredField] = '';
return example;
},
{} as Record<string, string>,
);
}
return result;
};
export const computeSchemaComponents = ( export const computeSchemaComponents = (
objectMetadataItems: ObjectMetadataEntity[], objectMetadataItems: ObjectMetadataEntity[],
): Record<string, OpenAPIV3_1.SchemaObject> => { ): Record<string, OpenAPIV3_1.SchemaObject> => {
return objectMetadataItems.reduce( return objectMetadataItems.reduce(
(schemas, item) => { (schemas, item) => {
schemas[capitalize(item.nameSingular)] = computeSchemaComponent(item); schemas[capitalize(item.nameSingular)] = computeSchemaComponent(item);
schemas[capitalize(item.namePlural)] = computeBatchSchemaComponent(item); schemas[capitalize(item.nameSingular) + ' with Relations'] =
computeRelationSchemaComponent(item);
return schemas; return schemas;
}, },

View File

@ -11,7 +11,10 @@ import {
getFindOneResponse200, getFindOneResponse200,
getUpdateOneResponse200, getUpdateOneResponse200,
} from 'src/engine/core-modules/open-api/utils/responses.utils'; } from 'src/engine/core-modules/open-api/utils/responses.utils';
import { getRequestBody } from 'src/engine/core-modules/open-api/utils/request-body.utils'; import {
getArrayRequestBody,
getRequestBody,
} from 'src/engine/core-modules/open-api/utils/request-body.utils';
export const computeBatchPath = ( export const computeBatchPath = (
item: ObjectMetadataEntity, item: ObjectMetadataEntity,
@ -22,7 +25,7 @@ export const computeBatchPath = (
summary: `Create Many ${item.namePlural}`, summary: `Create Many ${item.namePlural}`,
operationId: `createMany${capitalize(item.namePlural)}`, operationId: `createMany${capitalize(item.namePlural)}`,
parameters: [{ $ref: '#/components/parameters/depth' }], parameters: [{ $ref: '#/components/parameters/depth' }],
requestBody: getRequestBody(capitalize(item.namePlural)), requestBody: getArrayRequestBody(capitalize(item.nameSingular)),
responses: { responses: {
'201': getCreateManyResponse201(item), '201': getCreateManyResponse201(item),
'400': { $ref: '#/components/responses/400' }, '400': { $ref: '#/components/responses/400' },

View File

@ -11,3 +11,19 @@ export const getRequestBody = (name: string) => {
}, },
}; };
}; };
export const getArrayRequestBody = (name: string) => {
return {
required: true,
content: {
'application/json': {
schema: {
type: 'array',
items: {
$ref: `#/components/schemas/${name}`,
},
},
},
},
};
};

View File

@ -19,7 +19,7 @@ export const getFindManyResponse200 = (
items: { items: {
$ref: `#/components/schemas/${capitalize( $ref: `#/components/schemas/${capitalize(
item.nameSingular, item.nameSingular,
)}`, )} with Relations`,
}, },
}, },
}, },
@ -54,7 +54,9 @@ export const getFindOneResponse200 = (
type: 'object', type: 'object',
properties: { properties: {
[item.nameSingular]: { [item.nameSingular]: {
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`, $ref: `#/components/schemas/${capitalize(
item.nameSingular,
)} with Relations`,
}, },
}, },
}, },