This plugin is designed to integrate Postman functionality into your Backstage application seamlessly. It simplifies the addition of a Postman card to your API views and enables dynamic retrieval of Postman resources like collections and APIs. Linking your APIs with Postman collections or APIs empowers consumers to interact effortlessly with these resources within the Postman interface. This includes features such as a Run in Postman
button and the ability to dynamically fetch collections or APIs from Postman and add them to your API list using an Entity Provider
.
- Disclaimer and Plugin Compatibility
- Plugin Features
- Installation
- Configure Postman Frontend Plugin for Backstage
- Configure Postman Backend Plugin for Backstage
- Configure Backend Content Security Policy to display embedded pictures (optional)
- Postman Metadata Guide
These backstage plugins are not officially supported by Postman and are intended for Backstage users to integrate Postman into their API documentation easily. They have been successfully tested with Backstage v1.22, v1.23 and 1.28. Please file an issue if you are using a newer version of Backstage so that we can recommend how to integrate best under those circumstances.
This plugin offers several views which you can use to display published API information stored in Postman, show collections with a Run In Postman button and allow you to view your Postman monitor results on the API page.
Displays your published Postman API data in Backstage, allowing you to access both the API information and the published API collections.
Refer to the Postman API Metadata for the parameters needed to display this view.
This view displays the collection(s) of a given API stored in Postman. It includes a Run in Postman button, which is activated based on the collection ID(s) or tag defined in the entities.yaml
file.
Refer to the Postman Collections Metadata to see the parameters needed to display this view.
This view shows the health of your API as determined by a Postman monitor. The monitor can be displayed using its name
or id
.
For more details, refer to this section.
You can also use this plugin to dynamically fetch Postman APIs or collections using Postman tags. For more details, please refer to this section.
A Governance Checks view will be added in future versions of this plugin.
# From your Backstage root directory
yarn --cwd packages/app add @postman-solutions/postman-backstage-plugin
yarn --cwd packages/backend add @postman-solutions/postman-backstage-backend-plugin
The next step is configuring both plugins as described in the next two sections.
The Postman frontend plugin enables you to link your APIs to their corresponding collections, published APIs and monitors within Postman. You can also discover APIs and collections within your Postman Team that have been tagged with a tag of your choice and add them to the catalogue.
It is a community-driven initiative to extend Backstage functionalities with Postman.
Important
Please note that the frontend plugin will not function without the backend plugin.
Refer to the installation steps for the backend plugin here.
- Configure your Postman API key in your local
app-config.yaml
or productionapp-config.production.yaml
file:
Caution
The apiKey
in the configuration should not belong to an admin or super admin user, as this would grant access to all collections and APIs in the team. Instead, use an apiKey
from a user with access only to the information that can be safely displayed to the authenticated developer audience in Backstage. This principle of least privilege helps to maintain tight control over your Postman data and reduces the potential impact if a user adds a reference to an entity in a private workspace or accidentally tags a private API with the tag used by the Postman entity provider.
postman:
baseUrl: https://api.postman.com
apiKey: ${YOUR_API_KEY_HERE}
To get a Postman API Key, follow the instructions here.
- Import and add the component in your
packages/app/src/components/Catalog/EntityPage.tsx
page to display the Postman card on your API page.
// ... other imports here
import { PostmanCard } from '@postman-solutions/postman-backstage-plugin';
// ... other components
const apiPage = (
<EntityLayout>
<EntityLayout.Route path="/" title="Overview">
// ... other elements
<Grid item md={6} xs={12}>
<PostmanCard />
</Grid>
// ... other elements
</EntityLayout.Route>
</EntityLayout>
// ...
);
// ...
This postman-backend
plugin provides some Postman services that the Postman frontend plugin will use to render the different component views.
Before you begin, ensure you have the following:
- Make sure the Postman Frontend Plugin is already installed and configured
- A running instance of Backstage
- Node.js and npm installed (Node.js 18.x or later is recommended)
- Access to Postman API credentials
This guide provides instructions for configuring your application to interact with the Postman API using the app-config.yaml
file. Follow the steps below to set up your environment correctly.
API Key Setup: First, make sure to include the base URL and set an environment variable POSTMAN_API_KEY
with your Postman API key in the configuration file if not done already.
Caution
The apiKey
in the configuration should not belong to an admin or super admin user, as this would grant access to all collections and APIs in the team. Instead, use an apiKey
from a user with access only to the information that can be safely displayed to the authenticated developer audience in Backstage. This principle of least privilege helps to maintain tight control over your Postman data and reduces the potential impact if a user adds a reference to an entity in a private workspace or accidentally tags a private API with the tag used by the Postman entity provider.
postman:
baseUrl: https://api.postman.com
apiKey: ${POSTMAN_API_KEY}
-
Entity Provider Setup: The plugin includes an entity provider to fetch API assets from Postman periodically using a Postman tag. Tags can be added to collections or Postman APIs. To use this option, please add the following settings to your
app-config.yaml
:Parameter Schema Type Optional Description postman/team
string Yes Name of your Postman team. For a team URL like https://myteam.postman.co
, your team name would bemyteam.postman.co
.postman/owner
string Yes Owner of the API assets. The default is "postman". Consider creating a User or Group for this owner. postman/synchEntitiesWithTag
string Yes Postman tag used to fetch API assets. postman/entityProviderSynchInterval
string Yes Interval (in hours) for fetching the API assets from Postman. postman/system
string Yes System of the API assets. The default is "main". Example configuration:
postman:
baseUrl: https://api.postman.com
apiKey: ${POSTMAN_API_KEY}
team: my-team.postman.co
synchEntitiesWithTag: backstage
owner: postman-team
entityProviderSynchInterval: 2
system: my-system
-
Caching Options: The Postman backend plugin supports caching. Configure cache settings by adding the following properties:
Parameter Schema Type Optional Description postman/cache/ttl
number Yes Cache expiry time in milliseconds. The default is 600000 (10 minutes). Example configuration for a custom cache duration:
postman: baseUrl: https://api.postman.com apiKey: ${POSTMAN_API_KEY} team: my-team.postman.co cache: ttl: 300000 # 5 minutes
If you prefer not to utilise caching and always get the latest information from Postman, you can set the TTL value to 0 or any value smaller than the interval at which the entity service refreshes.
- Modify file
packages/backend/src/index.ts
, and add the following to it:
...
import { createBackend } from '@backstage/backend-defaults';
// new code after other imports
import { loggerToWinstonLogger, CacheManager } from '@backstage/backend-common';
import {
coreServices,
createBackendPlugin,
createBackendModule,
} from '@backstage/backend-plugin-api';
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
import { PostmanEntityProvider, createRouter as postmanRouter } from '@postman-solutions/postman-backstage-backend-plugin';
const backend = createBackend();
...
backend.add(import('@backstage/plugin-search-backend-module-techdocs/alpha'));
// new code after all other plugins have been added to backend
backend.add(createBackendPlugin({
pluginId: 'postman',
register(env) {
env.registerInit({
deps: {
config: coreServices.rootConfig,
logger: coreServices.logger,
httpRouter: coreServices.httpRouter,
},
async init({ config, logger, httpRouter }) {
const legacyLogger = loggerToWinstonLogger(logger);
httpRouter.use(await postmanRouter({ config, logger: legacyLogger }));
httpRouter.addAuthPolicy({
path: '/:id',
allow: 'unauthenticated',
})
},
});
},
}));
// optional for the entity service
const postmanEntityServiceModule = createBackendModule({
pluginId: 'catalog', // name of the plugin that the module is targeting
moduleId: 'custom-extensions',
register(env) {
env.registerInit({
deps: {
catalog: catalogProcessingExtensionPoint,
config: coreServices.rootConfig,
logger: coreServices.logger,
scheduler: coreServices.scheduler,
},
async init({ catalog, config, logger, scheduler}) {
const cacheManager = CacheManager.fromConfig(config);
const cache = cacheManager.forPlugin('postman').getClient({defaultTtl: config?.getNumber('postman.cache.ttl') ?? 60000 })
const postmanEntityProvider = PostmanEntityProvider.fromConfig(config, {logger: logger, cache})
const postmanEntityProviderSynchInterval = config?.getNumber('postman.entityProviderSynchInterval') ?? 5;
catalog.addEntityProvider(postmanEntityProvider);
await scheduler.scheduleTask({
id: 'run_postman_entity_provider_refresh',
fn: async () => {
await postmanEntityProvider.run();
},
frequency: { minutes: postmanEntityProviderSynchInterval },
timeout: { minutes: 10 },
});
},
});
},
});
backend.add(postmanEntityServiceModule);
backend.start();
- Create a new file named
packages/backend/src/plugins/postmanbackend.ts
, and add the following to it:
import { PluginEnvironment } from '../types';
import { createRouter } from '@postman-solutions/postman-backstage-backend-plugin';
export default async function createPlugin({
logger,
config,
}: PluginEnvironment) {
return await createRouter({ logger, config });
}
- Next, let's wire this into the overall backend router, edit
packages/backend/src/index.ts
:
import postmanbackend from './plugins/postmanbackend';
// ...
async function main() {
// ...
// Add this line under the other lines that follow the useHotMemoize pattern
const postmanBackEndEnv = useHotMemoize(module, () => createEnv('postman-backend'));
// ...
// Insert this line under the other lines that add their routers to apiRouter in the same way
apiRouter.use('/postman', await postmanbackend(postmanBackEndEnv));
// ...
}
- (optional) you can run
yarn start-backend
from the root directory to start the backend server
The Postman EntityProvider is an optional component that allows you to dynamically retrieve Postman APIs and collections that have been tagged with a certain Postman tag, e.g. backstage
.
In order for it to work, you would need to add some more properties to your local app-config.yaml
or production app-config.production.yaml
file:
postman:
baseUrl: https://api.postman.com
apiKey: ${POSTMAN_API_KEY}
synchEntitiesWithTag: TAG_NAME
entityProviderSynchInterval: SYNC_FREQUENCY_IN_MINUTES (optional)
Additionally, if you are using an older version of Backstage ( < 1.24) you would need to insert the following lines into your packages/backend/src/plugins/catalog.ts
file:
...
// new code after other imports
import { PostmanEntityProvider } from '@postman-solutions/postman-backstage-backend-plugin';
import { CacheManager } from '@backstage/backend-common';
...
...
const builder = CatalogBuilder.create(env);
// new code after builder got instantiated
const cacheManager = CacheManager.fromConfig(env.config);
const cache = cacheManager.forPlugin('postman').getClient({defaultTtl: env.config?.getNumber('postman.cache.ttl') ?? 60000 })
const postmanEntityProvider = PostmanEntityProvider.fromConfig(env.config, {logger: env.logger, cache})
const postmanEntityProviderSynchInterval = env.config?.getNumber('postman.entityProviderSynchInterval') ?? 5;
builder.addEntityProvider(postmanEntityProvider);
...
...
await processingEngine.start();
// new code after processing engine started
await env.scheduler.scheduleTask({
id: 'run_postman_entity_provider_refresh',
fn: async () => {
await postmanEntityProvider.run();
},
frequency: { minutes: postmanEntityProviderSynchInterval },
timeout: { minutes: 10 },
});
...
For newer versions of Backstage (v1.24+), we included the entity service initialization code in our modifications for packages/backend/src/index.ts
.
If your Postman API docs contain embedded pictures like this one
you would need to include the potential image sources into the backend section of your app-config.production.yaml
:
backend:
csp:
img-src:
# "'self'" and 'data' are from the backstage default but must be set since img-src is overwritten
- "'self'"
- 'data:'
- https://content.pstmn.io
- https://i.imgur.com
- https://avatars.githubusercontent.com
This section provides an overview of the metadata object for this Postman plugin in the context of the Backstage implementation. All parameters should only be defined with the kind: API
in your YAML file.
All three options, API, Collections, and Monitor, can be used in conjunction.
These parameters are common across different kinds of entities:
Parameter | Schema Type | Optional | Description |
---|---|---|---|
postman/domain |
string | Yes | The sub-domain of your Postman instance. E.g. if your Postman URL is postman-demo.postman.co , use postman-demo . If not defined, the application will use go.postman.co to redirect users to Postman. |
postman/workspace/id |
string | No | The ID of your Postman workspace. This ID will be used to construct the links to redirect to Postman. |
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: calculation-grpc-api
postman/domain: "postman-demo"
postman/workspace/id: "YOUR_WORKSPACE_ID_HERE"
Parameter | Schema Type | Optional | Description |
---|---|---|---|
postman/api/id |
string | No | The ID of your Postman API. |
postman/api/name |
string | Yes | (optional) The name of your Postman API. If referenced, this value will be used to fetch the API Postman monitor(s) using the API name. |
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: calculation-grpc-api
postman/domain: "postman-demo"
postman/workspace/id: "YOUR_WORKSPACE_ID_HERE"
postman/api/id: "YOUR_POSTMAN_API_ID_HERE"
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: calculation-grpc-api
postman/domain: "postman-demo"
postman/workspace/id: "YOUR_WORKSPACE_ID_HERE"
postman/api/id: "YOUR_POSTMAN_API_ID_HERE"
postman/api/name: "YOUR_POSTMAN_API_NAME"
Parameter | Schema Type | Optional | Description |
---|---|---|---|
postman/collection/id |
string | Yes | The ID of your Postman collection. |
postman/collections/ids |
array | Yes | An array of IDs of your Postman collections. |
postman/collections/tag |
string | Yes | A string specifying the collection tag to retrieve. |
postman/collections/pagination |
string | Yes | A 'true' or 'false" value to indicate whether you want to paginate through the results. |
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: calculation-grpc-api
postman/collection/id: "YOUR_COLLECTION_ID"
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: calculation-grpc-api
postman/collections/pagination: 'true'
postman/collections/tag: "YOUR_COLLECTION_TAG_HERE"
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: calculation-grpc-api
postman/collections/ids: ["YOUR_FIRST_COLLECTION_ID", "YOUR_SECOND_COLLECTION_ID"]
Parameter | Schema Type | Optional | Description |
---|---|---|---|
postman/monitor/id |
string | No | The ID of your Postman monitor. |
postman/monitor/name |
string | No | The name of your Postman monitor. |
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: calculation-grpc-api
postman/monitor/id: "YOUR_MONITOR_ID_HERE"
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: calculation-grpc-api
postman/monitor/name: "YOUR_MONITOR_NAME_HERE"
This project is licensed under the MIT License. Feel free to use, modify, and distribute the code according to the terms of the license.
Thank you for considering contributing to this project. For more information on how to get started, please check out the contribution guidelines.
We expect all contributors to adhere to the Code of Conduct. Please review the guidelines before contributing to ensure a positive and inclusive community for everyone.
If you have any questions, concerns, or suggestions regarding this project, feel free to contact @aphanor-postman or @jonico.