API spec management
The API spec management commands allow you to validate and manipulate your API specs, for example validating that your OpenAPI spec is compliant with the standard, or merging multiple specs together.
Command | Description |
---|---|
liblab bundle | Bundle an OpenAPI spec file to resolve all external references |
liblab merge | Merge two or more OpenAPI specs into one |
liblab validate | Validate your OpenAPI spec file |
liblab bundle
The liblab bundle
command allows you to bundle an OpenAPI spec file to resolve all external references, including remote and URL references. This command creates a single OpenAPI spec file that contains all the referenced components that can then be used to generate an SDK.
liblab bundle <spec-file> [--output=<output-spec-file>]
The spec-file
is the path to the OpenAPI spec file that you want to bundle. This can be a JSON or YAML file, either a local file or a publicly reachable URL. This file can have external references to either local spec files, or publicly reachable URLs.
For example, the following main spec:
openapi: 3.1.0
paths:
/soda:
get:
responses:
'200':
content:
application/json:
schema:
$ref: 'https://exciting.soda/components.yaml#/components/schemas/Soda'
That references the following external spec:
openapi: 3.1.0
components:
schemas:
Soda:
When bundled will give:
openapi: 3.1.0
paths:
/soda:
get:
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Soda'
components:
schemas:
Soda:
The bundled spec is created by taking the given spec, and adding in just the referenced components
from the external specs - nothing else (such as paths
or servers
) is taken from the external specs. If you want to merge specs to include things like paths
, use the liblab merge
command instead.
By default, bundled spec is written to a YAML output file, defaulting to bundledSpec.yaml
if the --output
parameter is not set. If you want output a JSON file, or specify a different file name, you can set this using the --output
parameter.
Optional parameters
Parameter | Description |
---|---|
--output -o | The output file that the bundled spec will be written to. This can be a JSON or YAML file, and the new spec is created in the relevant format, defaulting to YAML if the file extension is not recognized. If this is not set, the merged spec will be written to bundledSpec.yaml in the current working directory. |
liblab merge
The liblab merge
command allows you to merge multiple OpenAPI spec files together into a single file by merging all the paths and components together.
liblab merge <spec-folder> [--main=<main-spec-file>]
[--output=<output-spec-file>]
The spec-folder
is the path to a local folder that contains all the spec files that you want to merge.
Once your API specs are merged, you can use the merged spec to generate an SDK that supports the APIs represented in all the individual specs.
The merge process is done in the following order:
-
The main spec file is used as the base of the merge. If the main spec is not specified using
--main
, the first spec file found in thespec-folder
will be used as the main spec. This main spec will provide all the API metadata, such as theinfo
section. -
The specs are validated to ensure there are no conflicts.
- Multiple specs cannot define the same path, this will lead to a conflict. For example, 2 specs with the path
/soda
will conflict. - Multiple specs can define the same schema, but the schema must be identical. Any differences will lead to a conflict.
- Multiple specs cannot define the same path, this will lead to a conflict. For example, 2 specs with the path
-
If there are conflicts, the merge process will stop and an error will be thrown, giving details of the conflict:
Terminal$ liblab merge ./specs
✖ Error: Unable to merge the specs.
> Error: Conflict on components => schemas : SodaValidationDetails in files: specs/soda.yaml
> specs/soda.yaml,specs/boba.yaml
> Please fix conflicts before running merge.Resolve the conflicts before running the merge again.
-
All other spec files in the
spec-folder
are merged with the contents of the main spec. This includes:- All unique servers
- All paths and operations, including their summary, description, operations, parameters, request body, and responses
- All unique input and output schemas
- All authentication schemes
-
The merged spec is written to the output spec file, defaulting to
mergedSpec.yaml
if the--output
parameter is not set.
For example, the following specs:
openapi: 3.1.0
info:
version: 1.0.0
title: Soda API
description: Exciting soda beverages
servers:
- url: https://exciting.soda
paths:
/soda:
get:
components:
schemas:
Soda:
openapi: 3.1.0
info:
version: 1.0.0
title: Boba API
description: Exciting boba beverages
servers:
- url: https://exciting.boba
paths:
/boba:
get:
components:
schemas:
Boba:
When merged will give:
openapi: 3.1.0
info:
version: 1.0.0
title: Soda API
description: Exciting soda beverages
servers:
- url: https://exciting.soda
- url: https://exciting.boba
paths:
/soda:
get:
/boba:
get:
components:
schemas:
Soda:
Boba:
Notice that the info
section from the main spec is used, giving a title of Soda API
. Otherwise, the servers
, paths
, and components
are merged together.
Merging supports both local references, and external references to other specs. For example, if you have multiple teams creating API specs that share common components, it is good practice to put these common components in a separate spec file and reference them in the other spec files. In the case, the liblab merge
command will be able to handle the references, and merge the common components into the output spec.
By default, the merged spec is written to a YAML output file, defaulting to mergedSpecs.yaml
if the --output
parameter is not set. If you want output a JSON file, or specify a different file name, you can set this using the --output
parameter.
Custom main spec
When you merge specs, the main spec is used to define core details, such as the info
section. Sometimes you may want these sections to be different in the combined spec from what is in all the other specs. For example, when each spec has a description of the one API, but you want a generic description for the combined API.
The recommended way to do this is to create a custom main spec that has no paths
or components
, but only has the info
section. You can then use this custom main spec as the main spec for the merge. The end result will have all the paths
and components
from all the other specs, but the info
section from the custom main spec.
For example, the following custom main spec:
openapi: 3.1.0
info:
version: 1.0.0
title: Soda and Boba SDK
description: Exciting soda and Boba beverages
When merged with the following:
openapi: 3.1.0
info:
version: 2.1.0
title: Soda API
description: Exciting soda beverages
servers:
- url: https://exciting.soda
paths:
/soda:
get:
components:
schemas:
Soda:
openapi: 3.1.0
info:
version: 3.4.7
title: Boba API
description: Exciting boba beverages
servers:
- url: https://exciting.boba
paths:
/boba:
get:
components:
schemas:
Boba:
Will give the following merged spec:
openapi: 3.1.0
info:
version: 1.0.0
title: Soda and Boba SDK
description: Exciting soda and Boba beverages
servers:
- url: https://exciting.soda
- url: https://exciting.boba
paths:
/soda:
get:
/boba:
get:
components:
schemas:
Soda:
Boba:
Optional parameters
Parameter | Description |
---|---|
--main -m | The main spec file that will be used as the base for the merge. If this is not set, the first spec file found in the spec-folder will be used as the main spec. |
--output -o | The output file that the merged spec will be written to. This can be a JSON or YAML file, and the new spec is created in the relevant format, defaulting to YAML if the file extension is not recognized. If this is not set, the merged spec will be written to mergedSpec.yaml in the current working directory. |
liblab validate
Validate your liblab config file and OpenAPI spec in interactive or non-interactive mode.
liblab validate [--nonInteractive] [--liblab-config=<value>]
The liblab CLI will validate your config file and your spec. If there are any errors in the config file, these will be printed out in the terminal. For example, if you spelt bearer
wrong for the auth
setting:
{
"auth": [
"bear"
],
...
}
You would get the following:
➜ my-api: liblab validate
Detected 1 error in the liblab config:
✗ Property "auth.0": Invalid enum value. Expected 'apikey' | 'basic' | 'bearer' | 'custom', received 'bear'
All the config issues will need to be fixed before you running the build command.
After the config validation, spec validation will run and check your API spec for any errors or warnings and summarize them. You will be asked what you would like to do with the validation issues:
➜ my-api: liblab validate
? What would you like to do with the validation issues? (Use arrow keys)
❯ Skip all API spec issues
Skip all API spec issues and add all issues to the ignore list in the config file
Review all API spec issues
Skip all API spec issues
- This will skip all warnings and errors in the spec.Skip all API spec issues and add all issues to the ignore list in the config file
- This will skip all warnings and errors in the spec and add them to the ignore list in the liblab config file. You will not be asked about these issues again if you run the validation command again.Review all API spec issues
- This will walk you through each warning and error in the spec one by one, with options to continue or ignore them.
If you decide to review all API spec issues, you would get:
[WARNING]: "info-contact" Info object must have "contact" object.
At: info
Lines: 2 - 8
? What would you like to do for this error?
❯ Continue without changes for now
Continue without changes for all similar cases
Add this instance to the ignore list
Add all similar errors to the ignore list
For each warning or error you get the following options:
Continue without changes for now
- This will continue the validation process, ignoring this instance of the warning or error only. You will be asked about this again if the validation comes across the same issue again.Continue without changes for all similar cases
- This will continue the validation process, ignoring all instances of this warning or error in the rest of the file.Add this instance to the ignore list
- This will add this specific warning or error to an ignore list in the liblab config file. You will not be asked about this issue again if you run the validation command again.Add all similar errors to the ignore list
- This will add all similar warnings or errors to the ignore list in the liblab config file. You will not be asked about this error again if you run the validation command again.
Select the option you want, or use ctrl + c
to exit the validation process to fix the issue in your spec.
The ignore list options allow you to always ignore certain warnings or errors that you may not care about. For example, if you were to add the instance of the warning above about the missing contact
object to the ignore list, you would get the following in your liblab.config.json
file:
{
...
"validationsToIgnore": [
{
"code": "info-contact",
"path": [
"info"
]
},
]
...
}
You can read more about this configuration setting in our config file reference.
Once you complete the validation, the output is written to a file called api-schema-validation.log
in your current directory. This lists all warnings and errors in your spec, with details of the line number, and links with suggestions on how to fix them.
1. [Warning] Info object must have "contact" object.
Object Path: info
Line: 2 - 8,
Char: 10 - 3
Documentation: https://docs.stoplight.io/docs/spectral/4dec24461f3af-open-api-rules#info-contact
...
It is recommended that you fix all errors and most warnings to get the highest quality SDK possible. You can learn more in our review your spec guide.
Optional parameters
Parameter | Description |
---|---|
--nonInteractive | Mode in which the validation is run, if not set, the validation is run in interactive mode. |
--liblab-config=<value> | The path to your liblab config file that defines the spec that you want to use. This can be a local path or a publicly reachable URL. If this is not set, the default config file path is liblab.config.json in the current working directory. |