I need to obtain the documentation for all the APIs that I have in ApiGateway, but I can only see the documentation for the last API. This is my class:
import Auth from '@aws-amplify/auth';
import { config } from './config';
import APIGateway, { GetExportRequest } from 'aws-sdk/clients/apigateway';
import { ICredentials } from '@aws-amplify/core';
import { Spec, SwaggerUIBundle } from 'swagger-ui-dist'
export const initSwagger = async (): Promise<void> => {
const credentials = await Auth.currentCredentials();
const apiGateway = createAPIGatewayClient(credentials);
const specs = await getAPIGatewaySpec(apiGateway);
renderUI(specs);
};
const createAPIGatewayClient = (credentials: ICredentials): APIGateway => new APIGateway({
region: config.region,
accessKeyId: credentials.accessKeyId,
secretAccessKey: credentials.secretAccessKey,
sessionToken: credentials.sessionToken,
});
const getAPIGatewaySpec = async (apiGateway: APIGateway): Promise<Spec[]> => {
const { items: apis } = await apiGateway.getRestApis().promise();
const data = await getAPIExports(apiGateway, apis);
if (!data) {
throw new Error('No documentation body received');
}
const blobToJson = function (binArray: any) {
const jsons = new Array();
for (let j = 0; j < binArray.length; j++) {
let str = '';
for (let i = 0; i < binArray[j].body.length; i++) {
str += String.fromCharCode(parseInt(binArray[j].body[i]));
}
jsons.push(JSON.parse(str));
}
return jsons;
};
const specs = blobToJson(data) as Spec[];
console.log('spec: ', specs)
console.log('spec.length: ', specs.length)
specs.forEach((spec) => {
spec.servers.forEach((server: { variables: { basePath: { default: string } } }) => {
const basePath = server.variables.basePath.default;
if (basePath.startsWith('/')) {
server.variables.basePath.default = basePath.substr(1);
}
});
});
return specs;
};
const getAPIExports = async (apiGateway: APIGateway, apis: APIGateway.ListOfRestApi | undefined) => {
if (!apis) return;
return Promise.all(
apis.map(async (api) => {
const req: GetExportRequest = {
restApiId: api.id,
stageName: config.apiGateway.stageName,
exportType: 'oas30',
accepts: 'application/json',
} as GetExportRequest;
return await apiGateway.getExport(req).promise();
}),
);
};
const renderUI = (specs?: Spec[]): void => {
if (!specs) {
return;
}
specs.forEach((spec) => {
SwaggerUIBundle({
spec: spec,
'dom_id': '#swagger',
deepLinking: true,
openapi: '3.0.0',
});
});
};
The spec contains all the specifications of my API and it looks like this:
spec:
(4) [{…}, {…}, {…}, {…}]
0: {openapi: '3.0.1', info: {…}, servers: Array(1), paths: {…}, components: {…}}
1: {openapi: '3.0.1', info: {…}, servers: Array(1), paths: {…}, components: {…}}
2: {openapi: '3.0.1', info: {…}, servers: Array(1), paths: {…}, components: {…}}
3: {openapi: '3.0.1', info: {…}, servers: Array(1), paths: {…}, components: {…}}
However, when I try to access the documentation for the other APIs, I can only see the specification for the last position in the array (position 3). This leads me to believe that SwaggerUIBundle is being overwritten during iteration. Even if I don't iterate the array, I still get the same result. Is there a way to solve this? Thank you in advance.
EDIT:
By the way, I'm using this implementation with some modifications: https://github.com/m-radzikowski/aws-swaggerui