feat: Improve JSON format of OpenAPI definition, allow YAML format

By default, OpenAPI definition will now have JSON with spaces instead of minified JSON, for better visualization in the UI.

Configuration `catalog.providers.backstageOpenapi.definitionFormat` was also added, and can take values `json` (default) or `yaml`, so organizations can use their preferred/standard format.

Signed-off-by: Gabriel Dugny <gabriel.dugny@believe.com>

# Conflicts:
#	yarn.lock
This commit is contained in:
Gabriel Dugny
2025-01-03 14:00:14 +01:00
parent 2ef1c5a4c3
commit 62842ee38a
6 changed files with 34 additions and 3 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-backstage-openapi': minor
---
feat: Improve JSON format of OpenAPI definition, allow YAML format
@@ -28,6 +28,7 @@ catalog:
- catalog
- events
- search
definitionFormat: 'yaml"' # Optional, defaults to 'json'
entityOverrides: # All optional
metadata:
name: 'my-name'
@@ -29,6 +29,11 @@ export interface Config {
* Properties to override on the final entity object.
*/
entityOverrides?: object;
/**
* The format of the definition.
* @defaultValue json
*/
definitionFormat: 'json' | 'yaml';
};
};
};
@@ -42,7 +42,8 @@
"cross-fetch": "^4.0.0",
"lodash": "^4.17.21",
"openapi-merge": "^1.3.2",
"uuid": "^11.0.0"
"uuid": "^11.0.0",
"yaml": "^2.7.0"
},
"devDependencies": {
"@backstage/cli": "workspace:^",
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import yaml from 'yaml';
import {
ANNOTATION_LOCATION,
ANNOTATION_ORIGIN_LOCATION,
@@ -155,6 +155,19 @@ const loadSpecs = async ({
return mergeSpecs({ baseUrl, specs });
};
const formatDefinition = (
definition: any,
format: string | 'json' | 'yaml',
) => {
if (format === 'json') {
return JSON.stringify(definition, null, 2);
}
if (format === 'yaml') {
return yaml.stringify(definition);
}
throw new Error(`Unsupported format type: ${format}`);
};
export class InternalOpenApiDocumentationProvider implements EntityProvider {
private connection?: EntityProviderConnection;
private readonly scheduleFn: () => Promise<void>;
@@ -236,6 +249,10 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider {
const configToMerge = this.config.getOptional(
'catalog.providers.backstageOpenapi.entityOverrides',
);
const formatConfig =
this.config.getOptionalString(
'catalog.providers.backstageOpenapi.definitionFormat',
) ?? 'json';
const baseConfig = {
metadata: {
@@ -262,7 +279,7 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider {
},
spec: {
type: 'openapi',
definition: JSON.stringify(
definition: formatDefinition(
await loadSpecs({
baseUrl: this.config.getString('backend.baseUrl'),
discovery: this.discovery,
@@ -270,6 +287,7 @@ export class InternalOpenApiDocumentationProvider implements EntityProvider {
plugins: pluginsToMerge,
logger,
}),
formatConfig,
),
},
};
+1
View File
@@ -5797,6 +5797,7 @@ __metadata:
openapi-merge: ^1.3.2
openapi3-ts: ^3.1.2
uuid: ^11.0.0
yaml: ^2.7.0
languageName: unknown
linkType: soft