OpenAPI Merge CLI
The `openapi-merge-cli` package provides a command-line interface for merging multiple OpenAPI 3.0 specification files into a single, consolidated specification. It is built upon the `openapi-merge` library, inheriting its core merging algorithm. The tool is currently at version 1.3.2 and appears to be actively maintained in sync with its underlying library. Its primary use case is consolidating specifications from various microservices for exposure behind a single API Gateway, offering features like robust conflict resolution for component names, flexible path modification (stripping or prepending segments), and granular operation selection based on tags. It also supports merging `info.description` fields with custom titles. Unlike many general-purpose OpenAPI tools, its feature set is specifically tailored for API Gateway integration scenarios.
Common errors
-
Error: No configuration file found at 'openapi-merge.json'. Please create one or specify a path with --config.
cause The `openapi-merge.json` file is missing in the current working directory or the specified path via `--config` is incorrect.fixCreate an `openapi-merge.json` file in your project root or specify its correct path using `openapi-merge-cli --config ./path/to/my-config.json`. -
Input file './missing-service.yaml' not found. Please check the path configured in openapi-merge.json.
cause An `inputFile` or `inputURL` specified in the `openapi-merge.json` configuration does not point to an existing or accessible file/URL.fixVerify that all `inputFile` and `inputURL` paths in your `openapi-merge.json` configuration are correct, accessible, and exist. -
Error: Component 'MySchema' already exists. Use the 'dispute' option in your configuration to resolve conflicts.
cause Two or more input OpenAPI files define a component (e.g., a schema, parameter, response) with the exact same name, and no `dispute` resolution strategy is configured for the conflicting input.fixAdd a `dispute` object (e.g., `{"prefix": "MyService"}`) to the relevant input entry in `openapi-merge.json` to automatically rename conflicting components. -
Invalid OpenAPI specification: missing required field 'openapi'
cause One of the provided input files is not a valid OpenAPI 3.0 specification, often due to missing top-level required fields or general malformation.fixValidate all input OpenAPI files against the OpenAPI 3.0 schema using a linter or validator (e.g., 'spectral lint') to identify and correct any structural issues.
Warnings
- gotcha The tool exclusively supports OpenAPI Specification 3.0.x. Older versions, such as OpenAPI 2.0 (Swagger), are not compatible and will result in parsing errors.
- gotcha When configuring `pathModification` for an input, the `stripStart` option is always applied before `prepend`. This deterministic order prevents unexpected path structures.
- gotcha If an operation has both `operationSelection.includeTags` and `operationSelection.excludeTags` defined, the `excludeTags` rule will always take precedence, ensuring the operation is omitted from the merged output.
- gotcha When component names (e.g., schemas, parameters) conflict between multiple input OpenAPI files, `openapi-merge-cli` requires explicit dispute resolution via the `dispute` configuration for that input to prevent unexpected overwrites or errors.
Install
-
npm install openapi-merge-cli -
yarn add openapi-merge-cli -
pnpm add openapi-merge-cli
Imports
- openapi-merge-cli command
openapi-merge-cli
npx openapi-merge-cli
- Global Installation
npm install openapi-merge-cli && openapi-merge-cli
npm install -g openapi-merge-cli && openapi-merge-cli
- Configuration File (openapi-merge.json)
openapi-merge-cli
openapi-merge-cli --config ./path/to/my-custom-config.json
Quickstart
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const configPath = path.join(__dirname, 'openapi-merge.json');
const outputPath = path.join(__dirname, 'output.swagger.json');
const config = {
"inputs": [
{ "inputFile": "./service-a.swagger.json" },
{
"inputFile": "./service-b.swagger.yaml",
"pathModification": { "prepend": "/api/v2" },
"operationSelection": { "includeTags": ["public"] }
}
],
"output": outputPath
};
// Dummy OpenAPI input files for demonstration
const serviceA = `{
"openapi": "3.0.0",
"info": { "title": "Service A", "version": "1.0.0" },
"paths": {
"/health": {
"get": {
"summary": "Health check A",
"responses": { "200": { "description": "OK" } }
}
}
}
}`;
const serviceB = `
openapi: 3.0.0
info:
title: Service B
version: 1.0.0
paths:
/users:
get:
tags:
- public
summary: List users B
responses:
'200':
description: OK
/admin:
get:
tags:
- private
summary: Admin endpoint B
responses:
'200':
description: OK
`;
try {
// Create dummy input files and configuration file
fs.writeFileSync(path.join(__dirname, 'service-a.swagger.json'), serviceA);
fs.writeFileSync(path.join(__dirname, 'service-b.swagger.yaml'), serviceB);
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
console.log('Created openapi-merge.json and dummy input files.');
console.log('Running openapi-merge-cli...');
// Execute the CLI tool using npx
execSync(`npx openapi-merge-cli --config ${configPath}`, { stdio: 'inherit' });
console.log(`OpenAPI specification merged to ${outputPath}`);
console.log('You can now inspect output.swagger.json');
// Optional: Clean up generated files
// fs.unlinkSync(configPath);
// fs.unlinkSync(path.join(__dirname, 'service-a.swagger.json'));
// fs.unlinkSync(path.join(__dirname, 'service-b.swagger.yaml'));
} catch (error) {
console.error('Failed to merge OpenAPI files:', error.message);
process.exit(1);
}