Spectral is a linting engine that helps you define custom rules and enforce them on JSON and YAML files. Postman supports Spectral v6 rules for the configurable API governance and API security rules for your team. Postman also supports ES6 syntax and CommonJS syntax for custom functions configurable in custom governance rules.
Spectral checks that the APIs defined in OpenAPI documents conform to API design guidelines using a specific set of rules. For example, you can use Spectral to check that all properties of all data models are in camel case, or that all operations have a summary.
A Spectral rule targets a given location using a JSON Path Plus expression, then tests the values it finds with a function
. It returns an error if the values don't conform to the rule.
This example shows how to check that the name of an API doesn't contain the word "API," regardless of case (for instance, "api" or "Api"):
rules:
api-name-doesnt-contain-api:
given: $.info.title
then:
function: pattern
functionOptions:
notMatch: /\b(api)\b/i
First, the rule targets the title
property of the info
object located at the root ($
) of the document with the JSON Path Plus expression $.info.title
. In then
, the function
named pattern
checks whether the value of the title
property doesn't match (functionOptions.notMatch
) the regular expression looking for the word api
in any case (/\b(api)\b/i
).
A Spectral document (often called a ruleset) has a rules
property that can have one or more rules. Spectral identifies each rule with a key, which can be any JSON-compatible string.
rules:
api-name-doesnt-contain-api:
# ...
api-name-length:
# ...
Postman supports many of Spectral's features, though not all.
Whether it's created within Postman or imported from another source, a Spectral document needs to contain the properties shown in this example:
rules:
api-name-doesnt-contain-api:
description: The API name must not contain the word API
message: The info.title value "{{value}}" contains the forbidden word API
severity: error
formats:
- oas2
- oas3
given:
- $.info
then:
- field: title
function: pattern
functionOptions:
notMatch: /\b(api)\b/i
To be valid in Postman, your Spectral document can't contain any properties beyond those listed here. For the full list of rules and their descriptions, see Spectral rule properties.
You'll find each rule defined in rules
in the Custom Rules section in the configurable API governance or API security pages.
Remember to turn on your custom rules after you create or import them.
Property | Description |
---|---|
description | An optional description of the rule. If you provide one, it will be shown in the configurable rules page for either API Governance or API Security. |
message | If the rule is triggered, the list of rule violations will contain the
If message isn't provided, the description is used instead. And if description isn't available, the rule's key (in rules ) is used. |
severity | The severity of the problem detected by the rule. The possible values are
|
resolved | Determines whether your OpenAPI document is a resolved or unresolved document when Spectral executes your rule. This affects whether Spectral resolves A
|
formats | The list of document formats to which the rule will be applied. The accepted values are:
By default, a rule will target all versions 2 and 3.x (the default value is [oas2,oas3] ). |
given | Required. This can be a list with at least one element or a single element. Each value is a JSON Path Plus expression that may return zero, one, or more elements. If |
then | Required. This can be a list with at least one element or a single element. If the given JSON Path Plus expressions return values, the functions will be applied to all of them. |
then.field | This optional name can be used if the value returned by the The keyword |
then.function | Required. The name of the function to use. You can use all Spectral core functions in Postman. For more information about Spectral core functions, see the Spectral documentation. Custom functions are supported in custom API Governance rules. |
then.functionOptions | May be required depending on the function. The options of the function. You can use all Spectral core functions in Postman. For more information about Spectral core functions, see the Spectral documentation. Custom functions are supported in custom API Governance rules. |
A JSON Path (or JSON Path Plus) expression aims to represent the path to some elements in a JSON or YAML document. For example, $.info.title
represents the title
property of the info
object located at the document's root ($
).
Initially, JSON Path was created to be XPath for JSON and aimed to represent the path to some element in an XML document. JSON Path Plus is an extension of JSON Path. It adds more operators and makes some behaviors of the original specification explicit.
You can use the official JSON Path Plus documentation to build and test your rules' given paths. Syntax Through Examples and the JSON Path Plus demo are both useful.
These examples show the typical JSON Path Plus features you'll need to create rules in Postman:
$.info.title
- The title
property inside the info
object, which is located at the document's root ($
).$.paths.*.*.responses
- All responses of all operations of all paths
. *
gets all elements inside an object or an array.$.paths.*[post,patch,put]
- All POST
, PATCH
, and PUT
operations across all paths
. [ ]
can be used to filter elements.$..properties
- All properties
of all schema objects wherever they're located (for example, in parameters, responses, or reusable components). ..
gets all elements in the path tree.In the following example, the rule is supposed to check that there's a description of the API. The way it's written, though, it will never return a rule violation when the description
isn't present in the info
object.
# this approach won't work!
rules:
info-description:
given: $.info.description
then:
function: truthy
If the given
path doesn't find any value, the then
checks won't be executed. This means you can't use the path $.info.description
to check that the API description is defined in the OpenAPI document. This verification must be done using the path $.info
, which will return the info
object and the field
value set with the name of the field you're looking for (in this example, description
).
# this approach will work
rules:
info-description:
given: $.info
then:
field: description
function: truthy
You can add custom governance functions to use in your custom governance rules. You can use these guidelines to write custom functions in JavaScript and add them to your custom governance rules. Postman supports ES6 syntax and CommonJS syntax for custom functions.
Postman recommends using ES6 syntax for your custom functions.
Your custom function must have the targetVal
parameter, the message
property in your return statement, and either the export default
declaration (ES6) or module.exports
object property (CommonJS) exporting your function.
To add a custom function to a rule, your rule must have the then.function
property whose value is the name of the file containing the custom function. The filename is defined using the Name field when you create a custom function.
Use the following parameters in your custom functions depending on your use case. You must add parameters to your custom function in the following order: targetVal
, options
, then context
.
You can use any parameter names you want. Postman expects the parameters to be in a specific order.
Parameter | Description |
---|---|
targetVal | Required. The first parameter you must add to your function. This can be any data type, such as a string or array. This is the value that the If you also define a value for the |
options | The second parameter you can add to your function. This is the optional value of the If your custom function accepts options, Postman recommends adding a JSON Schema to your custom function. A JSON Schema enables you to define and validate your custom function's options when editing your rule. This requires you to export your custom function using the |
context | The third parameter you can add to your function. You can use this optional parameter to access properties about the context in which the custom function is called. For example, you can access the
|
function myCustomFunction(targetVal, options, context) { ... }
Use the following properties to write the return statement in your custom functions depending on your use case.
Property | Description |
---|---|
message | Required. The message describing the rule violation. |
path | An optional path to an element in the document that triggers the rule violation. If you use the You can add the You can also add the |
return [
// Rule violation with the default targetVal path
{
message: `Value must be different from "${values.join(',')}".`,
},
// Rule violation with a custom path leveraging the default targetVal path
{
message: `Value must be different from "${values.join(',')}".`,
path: [...context.path, "a", "custom", "path"]
},
];
Required. Export your custom function. This enables you to add the custom function's filename to your custom rule using the then.function
property. The custom function name you export must match the name in the function declaration.
If your custom function accepts options, Postman recommends adding a JSON Schema to your custom function. A JSON Schema enables you to define and validate your custom function's options when editing your rule. This requires you to export your custom function using the
createRulesetFunction
Spectral function.
export default function-name
.module.exports = function-name
.function myCustomFunction(targetVal, options, context) { ... }
// ES6 syntax
export default myCustomFunction;
// CommonJS syntax
// module.exports = myCustomFunction;
You can import the following Spectral functions into your custom function file in Postman.
The createRulesetFunction
function is an optional Spectral function you can import from the @stoplight/spectral-core
module.
This function enables you to use a JSON Schema to define your custom function's options, enabling you to validate whether the options provided in your rule using then.functionOptions
match specific criteria. The JSON Schema must be nested inside of a JSON object. If the provided options don't match the JSON Schema, an error message will explain the issue when editing your rule.
If you use ES6 syntax, error messages refer to your custom function as
"<unknown>" function
.
Add a JSON Schema for each of the following to your JSON object:
Key | Description |
---|---|
input | Required. Postman expects a key named If the Enter the following to skip validation for the |
options | Required. Postman expects a key named options in the JSON object. This is the JSON Schema that defines the options parameter in your custom function. Options are provided in your rule using the then.functionOptions property. This JSON Schema enables you to define and validate whether the values of options matches specific criteria. |
{
// JSON Schema of the targetVal parameter
input: {
type: "string"
},
// JSON Schema of the options parameter
options: {
type: "object",
additionalProperties: false,
properties: {
values: {
type: "array"
}
},
required: ["values"],
},
},
When you export your custom function, call the createRulesetFunction
Spectral function and include a JSON object containing JSON Schemas and the custom function's name as arguments. For a complete example of using a JSON Schema with a custom function, see Check that a value isn't in a list (JSON Schema).
import { createRulesetFunction } from "@stoplight/spectral-core";
.export default createRulesetFunction(json-object, function-name);
.const { createRulesetFunction } = require("@stoplight/spectral-core");
.module.exports = createRulesetFunction(json-object, function-name);
.// ES6 syntax
import { createRulesetFunction } from "@stoplight/spectral-core";
// CommonJS syntax
// const { createRulesetFunction } = require("@stoplight/spectral-core");
function myCustomFunction(targetVal, options, context) { ... }
// ES6 Syntax
export default createRulesetFunction(
// CommonJS Syntax
// module.exports = createRulesetFunction(
{
// JSON Schema of the targetVal parameter
input: {
type: "string"
},
// JSON Schema of the options parameter
options: {
type: "object",
additionalProperties: false,
properties: {
values: {
type: "array"
}
},
required: ["values"],
},
},
myCustomFunction,
);
JSON Schema specification enables you to describe a JSON document using a standard format.
You can add a JSON Schema that defines and validates your custom function's options. To learn about adding a JSON Schema to your custom function, see the createRulesetFunction
Spectral function.
You can use the official JSON Schema documentation to learn more about describing a JSON document using this format.
The following examples show JSON Schema key-value pairs you can use to validate your custom function's options:
$.options
- The root object that contains the JSON Schema of the options
parameter, which is your custom function's options.$.options.type
- A validation keyword that defines a constraint on the JSON data. In this example, the value is object
, meaning the data must be a JSON object.$.options.properties
- An object whose values define the parameter used to pass options to your custom function. In this example, values
is a variable that stores the value of the options
parameter.$.options.required
- A validation keyword that's an array of strings containing keys from $.options.properties
. Add properties to the array if they must be defined in the JSON Schema. In this example, values
must be defined in the JSON Schema. {
input: {
type: "string"
},
options: {
type: "object",
additionalProperties: false,
properties: {
values: {
type: "array"
}
},
required: ["values"],
},
},
In the following example, the custom function named notInEnumeration
is in a file named not_in_enumeration
. The filename is defined using the Name field when you create a custom function.
If your custom function accepts options, Postman recommends adding a JSON Schema to your custom function. A JSON Schema enables you to define and validate your custom function's options when editing your rule. This requires you to export your custom function using the
createRulesetFunction
Spectral function.
The custom function checks the value of the option values
, which is defined in the Spectral document (or ruleset) using the then.functionOptions
property. The value of values
is a list of numeric strings. If targetVal
is a value already in the list, the rule violation is triggered.
After the custom function, export default
or module.exports
references the custom function's name. This exports the custom function, enabling you to add its filename to your rule using the then.function
property.
// filename: not_in_enumeration
function notInEnumeration(targetVal, options, context) {
const { values } = options;
if (values.includes(targetVal)) {
return [
{
message: `Value must be different from "${values.join(',')}".`,
},
];
}
}
// ES6 syntax
export default notInEnumeration;
// CommonJS syntax
// module.exports = notInEnumeration;
In the following example, the custom function named notInEnumeration
is in a file named not_in_enumeration
. The filename is defined using the Name field when you create a custom function.
Before the custom function, the createRulesetFunction
Spectral function is imported into the file. This enables you to define the expected options in a JSON Schema to validate whether the provided options in your rule match specific criteria.
The custom function checks the value of the option values
, which is defined in the Spectral document (or ruleset) using the then.functionOptions
property. The value of values
is a list of numeric strings. If targetVal
is a value already in the list, the rule violation is triggered.
After the custom function, export default
or module.exports
calls the createRulesetFunction
Spectral function and includes the following arguments: a JSON object containing JSON Schemas of the targetVal
parameter and options
parameter, and the custom function's name. This exports the custom function, enabling you to add its filename to your rule using the then.function
property.
Learn more about the JSON Schemas used in this example.
// filename: not_in_enumeration
// ES6 Syntax
import { createRulesetFunction } from "@stoplight/spectral-core";
// CommonJS Syntax
// const { createRulesetFunction } = require("@stoplight/spectral-core");
function notInEnumeration(targetVal, options, context) {
const { values } = options;
if (values.includes(targetVal)) {
return [
{
message: `Value must be different from "${values.join(',')}".`,
},
];
}
}
// ES6 Syntax
export default createRulesetFunction(
// CommonJS Syntax
// module.exports = createRulesetFunction(
{
// JSON Schema of the targetVal parameter
input: {
type: "string"
},
// JSON Schema of the options parameter
options: {
type: "object",
additionalProperties: false,
properties: {
values: {
type: "array"
}
},
required: ["values"],
},
},
notInEnumeration,
);
In the following example, the Spectral document has a rule named http-status-obsolete
that uses a custom function file named not_in_enumeration
, which is defined using the Name field when you create a custom function. The custom function file has a custom function named notInEnumeration
. The custom function filename is added to the rule using the then.function
property.
The custom function accepts options using the then.functionOptions
property, defining a property named values
that's a list of numeric strings. The value of then.functionOptions.values
is passed to the custom function notInEnumeration
. The custom function then checks whether a rule violation occurred at the given
path appended with the value of the then.field
property.
rules:
http-status-obsolete:
formats: [oas2, oas3]
severity: warn
message: "{{property}} is an obsolete or unused HTTP status code"
given: $.paths.*.*.responses
then:
field: "@key"
function: not_in_enumeration
functionOptions:
values: ["306","418","510"]
Last modified: 2024/07/12
Additional resources
Videos