Skip to content

Kontent-ai-Learn/kontent-ai-learn-oas-postman-converter

Repository files navigation

Kontent.ai OpenAPI to Postman Converter

This application creates a Postman collection for the Kontent.ai APIs. It takes the OpenAPI specifications generated by the Kontent.ai Learn API reference generator, converts them to Postman collections, tweaks the converted collections, and then merges them into a single collection.

Overview

  1. Fetches OpenAPI v3 specifications for the Kontent.ai APIs from the specified URLs.
    • The URLs are specified using an environment variable.
    • The names of the JSON files are hardcoded.
  2. Converts the downloaded OpenAPI specifications to Postman collections using the openapi-to-postman library.
  3. For each converted Postman collection, the app makes the following changes:
    1. Uses a Postman variable named environment_id for the :environment_id path variable in every request that requires environment ID in its path.
    2. Uses static base URLs for all requests instead of the {{baseUrl}} Postman variable.
    3. Removes extraneous Postman collection variables such as {{baseUrl}}.
  4. Merges the processed Postman collections into a single collection.

How to run locally

Prerequisites

  1. NodeJs v18 or higher
  2. IDE such as Visual Studio Code

Instructions

To run the app locally, provide environment variables in the .env.local config file.

ApiReferenceGhOwner=Kontent-ai-Learn
ApiReferenceGhBranch=new-main
ApiReferenceGhRepository=Redocly-API-reference
ApiReferenceGhUsername=kontent-ai-learn-bot
ApiReferenceGhEmail=learn.robot@kontent.ai
ApiReferenceGhAccessToken=x
ApiReferenceFileNames=delivery_api.json,management_api_v2.json,management_api_v3.json,subscription_api.json,sync_api.json

By default, the variables are read from environment variables and can be set up in app hosting platforms. The OpenAPI files to use are specified in the ApiReferenceFileNames variable.

  1. Open the src\workerScript.ts.
  2. Create a .env.local file based on the .env.local.template and configure all required settings (e.g., AccessToken, Github user details)
  3. In your terminal, run npm install.
  4. In your terminal, run npm run build.
  5. In your terminal, run npm run start.
  6. Make a request to http://localhost:3000/collection.json.

Import generated collection to Postman

To import the generated collection to your locally running Postman:

  1. In Postman, choose your workspace.
  2. Click Import.
  3. In the input field, provide a URL to the collection.json file that the app returns.
    • If running locally, the URL is http://localhost:3000/collection.json.
    • If deployed publicly, the URL is https://<domain>/collection.json.
  4. Press Enter.

Adjust what goes in the Postman collection

If you need to adjust the logic behind processing the OpenAPI files and converting them to Postman collections, check the functions in collectionProcessing.ts.

In the convertSpecToPostmanCollection function, modify the parameters used for the conversion with openapi-to-postman.

const convertSpecToPostmanCollection = async (spec: Spec): Promise<PostmanCollection> => {
return new Promise((resolve, reject) => {
Converter.convert(
{
type: 'string',
data: spec,
},
{
disableOptionalParameters: true,
exampleParametersResolution: 'Example',
folderStrategy: 'Tags',
includeAuthInfoInExample: true,
includeDeprecated: false,
optimizeConversion: false,
stackLimit: 50,
requestParametersResolution: 'Schema',
},
(err: Error, conversionResult: PostmanCollection) => {
if (conversionResult.result) {
const result = conversionResult.output[0].data;
debugLog(`Converted '${result.info.name}' spec to collection.`);
resolve(result);
}
else {
debugLog(`Could not convert due to '${conversionResult.reason}'.`);
reject(err);
}
},
);
});
};

In the processCollection function, specify how the Postman collection JSON should be modified.

const processCollection = (collection: PostmanCollection): ProcessedPostmanCollection => {
let processedCollection = Object.assign({}, collection);
let variables = collection.variable;
const folders = collection.item;
const baseUrl = getBaseUrlFromCollection(collection);
if (variables.length > 0 && variables[0].key === 'baseUrl') {
processedCollection.variable = [];
}
const foldersWithRequests: ReadonlyArray<any> = folders.map((folder: any) => {
let requests = folder.item;
if (requests.length > 0) {
requests.forEach((requestInfo: any) => {
let requestDefinition = requestInfo.request;
let responses = requestInfo.response;
// Use a variable for environment ID
if (requestDefinition.url.variable.length > 0 &&
requestDefinition.url.variable[0].key === 'environment_id') {
requestInfo.request.url.variable[0].value = '{{environment_id}}';
}
// Use a hardcoded base URL for requests
if ((requestDefinition.url.host.length > 0) &&
(requestDefinition.url.host[0] === '{{baseUrl}}')) {
requestInfo.request.url.host[0] = baseUrl;
}
// Use a hardcoded base URL for responses
responses.forEach((response: any, responseIndex: number) => {
if ((response.originalRequest.url.host.length > 0) &&
(response.originalRequest.url.host[0] === '{{baseUrl}}')) {
requestInfo.response[responseIndex].originalRequest.url.host[0] = baseUrl;
}
});
});
return folder;
}
return null;
}).filter(Boolean);
processedCollection.item = foldersWithRequests;
debugLog('Processed collection for ' + collection.info.name);
return processedCollection;
};

In themergeCollections function, specify how the processed Postman collections should be merged. For example, this is where we're adding the manually created Postman collection for GraphQL API (see GRAPHQL_API_COLLECTION) because GraphQL cannot be described using OpenAPI.

const mergeCollections = (collections: ReadonlyArray<ProcessedPostmanCollection>): MergedCollection => {
const folders = collections.map(collection => ({
name: collection.info.name,
item: collection.item,
description: collection.info.description.content,
auth: collection.info.name.includes('Management API') ? ManagementAPI_AUTH
: collection.info.name.includes('Subscription API') ? SubscriptionAPI_AUTH
: NO_AUTH,
event: [],
}));
const mergedCollection = Object.assign({}, NEW_COLLECTION_TEMPLATE, { item: [GRAPHQL_API_COLLECTION, ...folders] });
debugLog('Merged processed collections');
return mergedCollection;
};

The order of the API references in the Postman collection: Delivery GraphQL API is followed by the API references ordered as specified in the ApiReferenceFileNames env variable.

How To Contribute

Feel free to open a new issue where you describe your proposed changes or even create a new pull request from your branch with proposed changes.

Licence

All source code is published under the MIT licence.