Merge Multiple API Definitions
If you have multiple API specification documents and wish to create a unified API Portal or obtain a single SDK per language out of them, you can use our merging feature to combine the API specifications into one. The merging feature can also allow you to transform multiple API specifications into a single API specification in a format of your choice using API Transformer.
It is possible to merge together API specification documents of different formats e.g. OpenAPI, RAML, etc.
Merging multiple API specification documents should not be confused with importing or transforming a single API specification split into multiple files which is handled by the importer/Transformer automatically.
How Does Merging Work?
When multiple API definitions are provided as input, the merger selects two API definitions at a time and merges them together. The output of the merged API is then merged with the third API definition and so on. By default, APIMatic merges API definitions using the Take Left merge strategy. When two API definition files are being merged, APIMatic will try to keep elements such as endpoints and schemas from both the APIs while some elements may only be picked from the first API. The merging strategy, therefore, varies from component to component. However, if there is a conflict, the value from the first (left) API definition will take precedence by default. The merging process can be easily configured which will be discussed later.
The process of merging two two API specifications is illustrated below:
Merging of more than two API specifications can look something like as shown below:
Merging Two API Specifications - A Basic Example
For this example, we will only consider merging two API specification documents for simplicity purposes. You can, however, add any number of specifications for merging.
Create a root directory in your local system, say
dir
.Take any two API specification documents (say
spec1.json
andspec2.json
) and place them in separate directories (saydir1
anddir2
respectively) within the root directorydir
as follows:dir\
dir1\
spec1.json
dir2\
spec2.jsonAdd an empty Metadata JSON file in the root directory and assign it the name
APIMATIC-META.json
dir\
dir1\
spec1.json
dir2\
spec2.json
APIMATIC-META.jsonOpen the Metadata file and add the following to enable merging.
{
"MergeConfiguration": {
"MergeApis": true,
"MergedApiName": "Merged API"
}
}If you do not intend to generate an SDK/portal but only want to perform a transformation, you will need to disable code-generation specific validation, which is performed during merging, by adding the flag
SkipCodeGenValidation
to the configuration merge settings as follows:{
"MergeConfiguration": {
"MergeApis": true,
"MergedApiName": "Merged API",
"MergeSettings": {
"SkipCodeGenValidation": true
}
}
}Save the changes and close the file.
ZIP the contents of the root directory without including the root directory itself. The resulting zipped file should be ready for upload to APIMatic for import or transformation. Make sure you are using the
.zip
format to ZIP your files.
Importing the Zipped File for SDK/Portal Generation
On the APIMatic Dashboard, click on the Import option.
Click on Browse and select the
.zip
file containing the API definitions to merge. Click on Import.Before import, the ZIP file will be validated for possible syntax/semantic issues.
Once the merged API definition is imported, it will be visible in the list of APIs in the Dashboard as shown below:
You can now create an API portal or generate SDKs for this merged API.
Transforming the Zipped File
On the APIMatic Dashboard, click on the Transform API option.
Click on Choose file and select the
.zip
file containing the API definitions to merge. Select the Export Format from the dropdown, then click on Convert.Before transformation, the ZIP file will be validated for possible syntax/semantic issues.
If validation passes, you can click on Proceed to start downloading of the converted merged output.
Validating the Zipped File
Before import or transformation, APIMatic performs validation of each of the API definition files that are to be merged as well as validation of the API definition created after merging. The validation involves checks to ensure that the API definitions are structurally correct and contain complete information to ensure comprehensiveness of the files. There are 3 levels of validation messages that you may encounter:
- Errors: Any syntax/semantic issues found in the API definition; for example, if a GET method contains a request body. API definition file import cannot proceed in case of an error. You will be required to fix the issues listed for your definition if that happens.
- Warnings: Any unexpected behaviour that may affect the output; for example, if the parameter example provided is invalid. Warnings will not halt API import, but it is recommended that you fix these issues so your API definition results in the best possible experience.
- Messages: Recommendations or suggestions that can help enhance your API definition and its completeness. For example, messages can point out that an endpoint description or a parameter example is missing. Messages will not halt API import.
API Merging
To perform merging of multiple API specifications, you need to correctly structure the input specifications and configure the merging process based on your needs. Each of these steps are discussed in detail below.
Directory Structure
Structuring the API specification documents correctly is essential for correct output. Some key points to note are:
1. Dedicated Sub-Directory for Each API Definition
Each API definition (whether it is a single file or composed of multiple files) needs to be placed in a dedicated sub-directory. There is no limit on the number of sub-directories, therefore, you can merge any number of API specification documents this way. The sub-directory can optionally contain a metadata file for configuring how the specification document in this directory needs to be imported. The available configurations are discussed here.
2. Parent Directory of Sub-Directories
The sub-directories need to be placed in a parent directory that must contain a metadata file at the same level with configurations to enable and customize merging of the specifications in the sub-directories.
3. Types of Sub-Directory Structuring in Parent Directory
Linear Sub-Directory Structure
In simpler cases, all sub-directories will likely be placed at the same level in the root directory i.e. a linear sub-directory structure. An example is shown below:
dir\
APIMATIC-META-MAIN.json // Will contain merge settings
spec1\
openapi.json
APIMATIC-META.json // Can contain any specific settings for CodeGen, import/export etc
spec2\
openapi.json
spec3\
schemas\
pet.raml
dog.raml
cat.raml
main.raml
APIMATIC-META.json
spec1
,spec2
, andspec3
are three dedicated sub-directories for the API specifications that are to be merged.spec3
is a RAML specification document split into multiple files whereas the OpenAPI specification documents inspec1
andspec2
comprises of a single file only.spec1
andspec3
each use a metadata fileAPIMATIC-META.json
to configure how thespec1
andspec3
are imported, respectively.A metadata file
APIMATIC-META-MAIN.json
is present in the root directorydir
that should contain the Merge Configuration Object to help enable and configure merging of its sub-directories. Therefore, its content can look something like:{
"MergeConfiguration": {
"MergeApis": true,
"MergeOrderOfDirectories": ["spec1", "spec2", "spec3"],
"MergedApiName": "Merged API",
"MergeSettings": {
"ConflictStrategy": "KeepLeft"
}
}
}infoThe order of the API definition files in the
MergeOrderOfDirectories
setting matters, as the merging will be applied based on this order.As can be seen from the example, it is possible to merge specifications of different formats like RAML and OpenAPI.
Nested Sub-Directory Structure
It is possible to nest sub-directories within another sub-directory. In such a case, the sub-directory becomes a parent directory and must contain the required metadata file to enable and configure merging of its child directories.
A nested sub-directory structure like this is recommended if out of all the API definitions that are required to be merged, some are semantically similar to each other (i.e. share common parts in their API definitions) while others are completely different. So, you structure in a way such that the similar ones are merged together first and their output is then merged with other remaining distinct API definitions. An example is shown below:
dir\
APIMATIC-META-MAIN.json
spec1\
spec3\
openapi.json
spec4\
openapi.json
APIMATIC-META-MAIN.json
spec2\
openapi.json
spec1
andspec2
are two dedicated sub-directories for API specifications and are placed directly in the root directorydir
.spec3
andspec4
are two dedicated sub-directories for API specifications but are placed in the parent directoryspec1
. Herespec3
andspec4
likely share some common parts in their API definitions.- The metadata file
APIMATIC-META-MAIN.json
inspec1
will contain the Merge Configuration Object and help enable merging ofspec3
andspec4
. Its content can look like the following:{
"MergeConfiguration": {
"MergeApis": true,
"MergeOrderOfDirectories": ["spec3", "spec4"],
"MergedApiName": "First API",
"MergeSettings": {
"ConflictStrategy": "KeepLeft"
}
}
} - The metadata file
APIMATIC-META-MAIN.json
in root directorydir
will contain the Merge Configuration Object and help enable merging ofspec1
andspec2
. Its content can look like the following:{
"MergeConfiguration": {
"MergeApis": true,
"MergeOrderOfDirectories": ["spec1", "spec2"],
"MergedApiName": "Merged API",
"MergeSettings": {
"ConflictStrategy": "KeepLeft"
}
}
} - The merging of the above directory structure will work as follows:
spec3
andspec4
will be merged first based on the configuration present in theAPIMATIC-META-MAIN.json
inspec1
.- The merged output of
spec1
from previous step will then be merged withspec2
based on the configuration present in theAPIMATIC-META-MAIN.json
metadata file in the root directorydir
.
Configuring the Merge Process
The merge process can be enabled and configured using a metadata file which is placed in the parent directory containing the sub-directories. The following two objects can be added in this file and help control how the sub-directories are imported and merged:
{
"MergeConfiguration": {
"MergeApis": true,
"MergeOrderOfDirectories": ["SpecDirectory1", "SpecDirectory2"],
"MergedApiName": "Merged API",
"MergeSettings": {
"ConflictStrategy": "KeepLeft"
}
},
"ImportSettings": {
"PreferJsonSchemaNameOverTitle": true
}
}
Global Import Settings
You can optionally provide global import settings in the root metadata file that will help control how all API specifications in the sub-directories are imported. The global import settings applied this way can be overridden for any API by providing import settings in the API's sub-directory metadata file.
Merge Configuration Object
This is a required object using which you can enable merging and optionally configure it as well.
Name: MergeConfiguration
Setting | Type | Purpose |
---|---|---|
MergeApis | Boolean | Required Enables merging of APIs. By default this is set to false . |
MergeSettings | Merge Settings Object | Settings to configure the merge process. See Merge Settings object for more detail. |
MergeOrderOfDirectories | Array[String] | Paths of the sub-directories to be merged, relative from the parent directory in which they are placed. The order of the API definition files in this list matters, as the MergeSettings configuration will be applied based on this order. |
MergedApiName | String | Name of the final merged API. |
Example:
{
"MergeApis": true,
"MergeOrderOfDirectories": ["SpecDirectory1", "SpecDirectory2"],
"MergedApiName": "Merged API",
"MergeSettings": {
"ConflictStrategy": "KeepLeft"
}
}
Merge Settings Object
Name: MergeSettings
This object allows configuration of the merge process when merging two APIs.
Setting | Type | Purpose | Default Value |
---|---|---|---|
ConflictStrategy | Enum[Merge Conflict Strategy] | Conflict strategy to use when a conflict arises during merge. | KeepLeft |
DescriptionConflictStrategy | Enum[Merge Conflict Strategy] | By default, the conflict strategy specified in ConflictStrategy will be used for resolving conflicts in descriptions. However, the default conflict strategy for descriptions can be overridden using this setting. | Value of ConflictStrategy |
DeepCompareFieldTypes | Boolean | Whether to compare field level referenced custom types/models by names only or by actually retrieving and comparing their model type definitions. | false |
AppendParentNameInNamingConflict | Boolean | Append parent name to entity when there is a conflict between names instead of appending a number at the end. | false |
SkipCodeGenValidation | Boolean | Configures validation strictness of individual APIs and the merged API. | false |
NumberStartIndexForNameConflict | Number | When resolving conflicts in names of components (e.g. endpoints), a number is appended at the end of the conflicting name to make it unique. This setting controls the starting value of this number. | 1 |
MergeMultipleAuthentication | Boolean | Allow more than one authentication schemes present in the individual APIs, or the APIs being combined, to be merged together. | true |
PrefixEntityNamesWithApiNameBeforeMerge | Boolean | This setting will prefix names of all entities of an API with the API's name before merging, in order to prevent conflicts when this API is merged with another. The entities renamed this way include models, endpoints, endpoint level test cases, authentication schemes and those of server configuration, etc. | false |
PostfixEntityNamesWithApiNameBeforeMerge | Boolean | This setting will postfix names of all entities of an API with the API's name before merging, in order to prevent conflicts when this API is merged with another. The entities renamed this way include models, endpoints, endpoint level test cases, authentication schemes and those of server configuration, etc. | false |
DeduplicateModels | Boolean | This setting will remove or rename any duplicate/redundant model definitions to prevent clashes of models during merge. If deduplication is disabled, the models of the two APIs being merged will simply be combined together. Disable deduplication of models only if you are sure that the APIs being merged have models with unique names. Note, that names are compared in a case-insensitive manner therefore, if two models are named status and Status they are considered conflicting and one of these must be renamed to prevent a clash. | true |
CompareModelsAndFieldsExamples | Boolean | When enabled, this setting will compare schema examples during the schema deduplication process in merging. (This step could be performance-costly.) | false |
Merge Conflict Strategy
When merging two APIs together, conflicts are possible e.g. entities with the same name can exist in both APIs but with different definitions. In such a case, one of the entities must be renamed to resolve the conflict. The merge conflict strategy helps the merger decide which of the conflicting entities to update or remove in order to resolve the conflict. The possible values of a merge conflict strategy and some details about them are given below:
Value | Details |
---|---|
KeepLeft | The conflicting entity from the left API will be picked up as is while that of the right API will be discarded or updated depending upon the type of the entity being merged. |
KeepRight | The conflicting entity from the right API will be picked up as is while that of the left API will be discarded or updated depending upon the type of the entity being merged. |
KeepBoth | If applicable, values of both conflicting entities will be combined without alteration. If this strategy is not applicable for an entity, the conflict resolution will fallback to using KeepLeft . |
Merge | If applicable, values of both conflicting entities will be merged together intelligently. Some alteration is possible. If this strategy is not applicable for an entity, the conflict resolution will fallback to using KeepLeft . |
Post-Processing the Merged Output
It is possible to configure, filter or override parts of the merged API definition in the same way it is done for a regular import or transformation. This is achieved by adding required configurations in the same metadata file that is provided in the parent directory and is used for enabling merging e.g. if you are looking to transform the merged output into OpenAPI and want extensions enabled when you do so, you can enable the export setting ExportExtensions
in your parent directory metadata file as follows:
{
"MergeConfiguration": {
"MergeApis": true,
"MergeOrderOfDirectories": ["SpecDirectory1", "SpecDirectory2"],
"MergedApiName": "Merged API",
"MergeSettings": {
"ConflictStrategy": "KeepLeft"
}
},
"ExportSettings": {
"ExportExtensions": true
}
}
This way the OpenAPI output file obtained after merging and then transforming the merged API definition will have extensions included.
For more details on available options to post-process a merged output, please see relevant section here.